from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework import status
from django.http import StreamingHttpResponse
from django.utils.encoding import escape_uri_path

from equity_admin.serializers_vouchers import *
from equity_mall.utils.pages import MyPage
from equity_mall.utils.utils import get_level_list, random_str, get_sign_HMACSHA1
from equity_admin.utils import get_stockinfo, get_alidiscountcoupon, get_meituan_acitivty
from equity_mall.utils.wash_level1 import ylx_api
from equity_admin.tasks import *


class AliDiscountCouponModelViewSet(ModelViewSet):

    pagination_class = MyPage
    search_fields = ('activity_name', 'template_id', 'product_no')
    filter_class = AliDiscountCouponFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        goods_tag_activity_id = self.request.query_params.get('goods_tag_activity_id', None)
        if self.action == 'list':
            level_id = self.request.query_params.get('level_id', None)
            if level_id:
                try:
                    level_list = get_level_list(level)
                    level_id = int(level_id)
                    if level_id in level_list:
                        level = Level.objects.filter(id=level_id).first()
                except:
                    pass
        if level.level == 0:
            queryset = AliDiscountCoupon.objects.all().order_by('-id')
        elif level.level == 1:
            queryset = AliDiscountCoupon.objects.filter(level__prov_id=level.id).order_by('-id')
        elif level.level == 2:
            queryset = AliDiscountCoupon.objects.filter(level__city_id=level.id).order_by('-id')
        elif level.level == 3:
            queryset = AliDiscountCoupon.objects.filter(level__district_id=level.id).order_by('-id')
        else:
            queryset = AliDiscountCoupon.objects.filter(level__branch_id=level.id).order_by('-id')
        if customizeactivity_id:
            try:
                customizeactivity = CustomizeActivity.objects.get(id=customizeactivity_id)
                if customizeactivity.activity_type == 1:
                    queryset = queryset.exclude(customizeactivityrules__customizeactivity_id=customizeactivity_id)
            except:
                pass
        if goods_tag_activity_id:
            goods_tag_activity = GoodsTagActivity.objects.filter(id=goods_tag_activity_id).first()
            if goods_tag_activity:
                today = datetime.datetime.now()
                queryset = queryset.filter(goods_tag=goods_tag_activity.goods_tag, publish_end_time__gte=today)
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponListModelSerializer
        else:
            return AliDiscountCouponRetrieveModelSerializer

    def check_template(self, request):
        user = self.request.iser
        coupon_channel = self.request.data.get('coupon_channel', None)
        platform_id = self.request.data.get('platform_id', None)
        template_id = self.request.data.get('template_id', None)
        if not coupon_channel:
            return Response({'error': '优惠券类型必传'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_channel) == '1':
            if not template_id:
                return Response({'error': '支付宝活动请传模板id'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=2).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_alidiscountcoupon(template_id, platform)
            if not data_dict['success']:
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['data']['dataVO']['form']['activityName']
                transaction_minimum = Decimal(data_dict['data']['dataVO']['form']['overAmount'])
                coupon_amount = Decimal(data_dict['data']['dataVO']['form']['overReduceAmount'])
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendStartTime']/1000)
                available_end_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendEndTime']/1000)
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '2':
            if not template_id:
                return Response({'error': '微信活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=1).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_stockinfo(template_id, platform)
            if 'code' in data_dict:
                return Response({'error': data_dict['message']}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_type'] != 'NORMAL':
                return Response({'error': '暂支持代金券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_use_rule']['coupon_type'] != 'NORMAL':
                return Response({'error': '暂不支持减至券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['stock_name']
                transaction_minimum = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']) / Decimal('100')).quantize(Decimal('0.00'))
                coupon_amount = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['coupon_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.strptime(data_dict['available_begin_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                available_end_time = datetime.datetime.strptime(data_dict['available_end_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = data_dict['stock_use_rule']['max_coupons']
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '5':
            if not template_id:
                return Response({'error': '美团活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=5).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_meituan_acitivty(template_id, platform)
            if data_dict['status'] == 'fail':
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            if not data_dict['data']:
                return Response({'error': '无效批次号'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['data']['titleShow']
                transaction_minimum = data_dict['data']['discountDetaiDtos'][0]['quotaValue']
                coupon_amount = data_dict['data']['discountDetaiDtos'][0]['reduceValue']
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.strptime(data_dict['data']['validBeginTime'], "%Y-%m-%d %H:%M:%S")
                available_end_time = datetime.datetime.strptime(data_dict['data']['assignEndTime'], "%Y-%m-%d %H:%M:%S")
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = data_dict['data']['totalCount']
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': '无效活动类型参数'}, status=status.HTTP_400_BAD_REQUEST)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        coupon_channel = self.request.data.get('coupon_channel', None)
        coupon_way = self.request.data.get('coupon_way', None)
        platform_id = self.request.data.get('platform_id', None)
        template_id = self.request.data.get('template_id', None)
        level_id = self.request.data.get('level_id', None)
        name = self.request.data.get('name', '')
        fn_order_id = self.request.data.get('fn_order_id', '')
        distribution_platform_id = self.request.data.get('distribution_platform_id', None)

        transaction_minimum = self.request.data.get('transaction_minimum', None)
        publish_start_time = self.request.data.get('publish_start_time', None)
        publish_end_time = self.request.data.get('publish_end_time', None)
        max_number = self.request.data.get('max_number', None)
        max_number_by_day = self.request.data.get('max_number_by_day', '0')
        max_number_by_user = self.request.data.get('max_number_by_user', '0')
        max_number_by_day_count = self.request.data.get('max_number_by_day_count', None)
        max_number_by_user_count = self.request.data.get('max_number_by_user_count', None)
        join_limit_by_bay = self.request.data.get('join_limit_by_bay', None)
        join_limit_by_bay_count = self.request.data.get('join_limit_by_bay_count', None)
        coupon_type = self.request.data.get('coupon_type', None)
        amount = self.request.data.get('amount', None)
        is_need_auth = self.request.data.get('is_need_auth', None)
        activity_description = self.request.data.get('activity_description', None)
        usetime_type = self.request.data.get('usetime_type', None)
        start_fixed_time = self.request.data.get('start_fixed_time', None)
        end_fixed_time = self.request.data.get('end_fixed_time', None)
        invalid_day = self.request.data.get('invalid_day', None)
        if not coupon_channel:
            return Response({'error': '优惠券类型必传'}, status=status.HTTP_400_BAD_REQUEST)
        if not coupon_way:
            return Response({'error': '优惠券派发方式必传'}, status=status.HTTP_400_BAD_REQUEST)
        if not level_id:
            return Response({'error': '活动归属层级必传'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            level = Level.objects.get(id=level_id)
        except:
            return Response({'error': '无效层级参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_way) not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']:
            return Response({'error': '优惠券派发方式参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_channel) == '1':
            if not template_id:
                return Response({'error': '支付宝活动请传模板id'}, status=status.HTTP_400_BAD_REQUEST)
            activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            if activity:
                return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=2).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_alidiscountcoupon(template_id, platform)
            if not data_dict['success']:
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['data']['dataVO']['form']['activityName']
                    transaction_minimum = Decimal(data_dict['data']['dataVO']['form']['overAmount'])
                    coupon_amount = Decimal(data_dict['data']['dataVO']['form']['overReduceAmount'])
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
                    available_begin_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendStartTime']/1000)
                    available_end_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendEndTime']/1000)
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    description = f'''1、红包有效期{available_begin_time.strftime('%Y.%m.%d %H:%M:%S')}-{available_end_time.strftime('%Y.%m.%d %H:%M:%S')}（请在红包详情页面关注红包具体有效期信息），红包不可拆分，不得提现、无法转赠、不得为他人付款，过期自动作废，无法使用，同时也不予补发。
        2、该红包适用于指定间连商家及门店，使用支付宝选择中国邮政储蓄银行借记卡且单笔实际支付金额大于{transaction_minimum}元时可抵扣使用（实际使用范围以红包可抵扣为准）。使用红包的订单若发生退款，订单可退金额及红包可退面额以消费者的退款页面信息为准。退回的红包若在有效期内则可继续使用，且使用规则不变；退回的红包若已过有效期则无法使用，且不予补发。
        3、支付宝端的中国邮政储蓄银行活动，仅限中华人民共和国境内的支付宝实名认证用户参与；同一用户活动期内仅能参加{data_dict['data']['dataVO']['form']['totalCountLimit']}次活动。同一支付宝账号、手机号、身份证、手机终端，符合以上任一条件均视为同一用户。
        4、为确保活动公平性，如用户出现不正当行为（如虚假交易、作弊、恶意套取现金、刷信等），银行有权撤销用户优惠资格，并有权收回用户获得的福利。
        5、本活动由中国邮政储蓄银行优惠发放，具体使用如有不明之处，请联系银行。'''
                    alidiscountcoupon_data['activity_description'] = description
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                    alidiscountcoupon_data['remain_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                    max_number_by_user = data_dict['data']['dataVO']['form']['totalCountLimit']
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user
                    alidiscountcoupon_data['coupon_type'] = 2
                    alidiscountcoupon_data['coupon_channel'] = 1
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 1
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        if data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT':
                            bankcard_type = 2
                        elif data_dict['data']['dataVO']['form']['bankCardType'] == 'CREDIT':
                            bankcard_type = 1
                        elif data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT_CREDIT':
                            bankcard_type = 3
                        else:
                            bankcard_type =4
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = bankcard_type
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        if data_dict['data']['dataVO']['form']['useTimeType'] == 'ABSOLUTELY':
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                            alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['startFixedTime']/1000)
                            alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] =  datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['endFixedTime']/1000)
                        elif data_dict['data']['dataVO']['form']['useTimeType'] == 'RELATIVE':
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                            alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['dataVO']['form']['invalidDays']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 4
                            alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['dataVO']['form']['invalidDays']
                        if 'countLimitRoundingType' in data_dict['data']['dataVO']['form']:
                            if data_dict['data']['dataVO']['form']['countLimitRoundingType'] == 'DAYS':
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                            elif data_dict['data']['dataVO']['form']['countLimitRoundingType'] == 'MONTHS':
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                            else:
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['dataVO']['form']['frequencyCountLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = data_dict['data']['dataVO']['form']['totalCountLimit']
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                    AliDiscountCouponOperationRecord.objects.create(
                        alidiscountcoupon_id=alidiscountcoupon.id,
                        create_user_id=user.id,
                        remark='创建活动'
                    )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '2':
            if not template_id:
                return Response({'error': '微信活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=1).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_stockinfo(template_id, platform)
            if 'code' in data_dict:
                return Response({'error': data_dict['message']}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_type'] != 'NORMAL':
                if str(coupon_way) not in ['9', '10']:
                    return Response({'error': '活动类型为立减与折扣,请选择对应派发方式'}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_use_rule']['coupon_type'] != 'NORMAL':
                return Response({'error': '暂不支持减至券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['stock_name']
                    transaction_minimum = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']) / Decimal('100')).quantize(Decimal('0.00'))
                    coupon_amount = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['coupon_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
                    available_begin_time = datetime.datetime.strptime(data_dict['available_begin_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                    available_end_time = datetime.datetime.strptime(data_dict['available_end_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    alidiscountcoupon_data['activity_description'] = data_dict['description']
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = data_dict['stock_use_rule']['max_coupons']
                    alidiscountcoupon_data['remain_number'] = data_dict['stock_use_rule']['max_coupons']
                    max_number_by_day = data_dict['stock_use_rule']['max_amount_by_day'] / data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']
                    max_number_by_user = data_dict['stock_use_rule']['max_coupons_per_user']
                    alidiscountcoupon_data['max_number_by_day'] = max_number_by_day
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user
                    alidiscountcoupon_data['coupon_type'] = 8
                    alidiscountcoupon_data['coupon_channel'] = 2
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 0
                    if fn_order_id:
                        alidiscountcoupon_data['fn_order_id'] = fn_order_id
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = 3
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                        alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = available_begin_time
                        alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = available_end_time
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 0
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = max_number_by_user
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = (Decimal(data_dict['stock_use_rule']['max_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                        AliDiscountCouponOperationRecord.objects.create(
                            alidiscountcoupon_id=alidiscountcoupon.id,
                            create_user_id=user.id,
                            remark='创建活动'
                        )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '3':
            if not all([publish_start_time, publish_end_time]):
                return Response({'error': '请设置活动时间'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                publish_start_time = datetime.datetime.strptime(publish_start_time, '%Y-%m-%d %H:%M:%S')
                publish_end_time = datetime.datetime.strptime(publish_end_time, '%Y-%m-%d %H:%M:%S')
            except:
                return Response({'error': '活动时间格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            if publish_end_time <= datetime.datetime.now():
                return Response({'error': '活动结束时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
            if publish_end_time <= publish_start_time:
                return Response({'error': '活动结束时间须大于开始时间'}, status=status.HTTP_400_BAD_REQUEST)
            if not activity_description:
                return Response({'error': '请上传活动说明'}, status=status.HTTP_400_BAD_REQUEST)
            if not max_number:
                return Response({'error': '请设置活动最大派发数'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                max_number = int(max_number)
            except:
                return Response({'error': '活动最大派发数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            if str(max_number_by_day) == '1':
                if not max_number_by_day_count:
                    return Response({'error': '请上传活动每天最大派发数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    max_number_by_day_count = int(max_number_by_day_count)
                except:
                    return Response({'error': '活动每天最大派发数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                if max_number_by_day_count > max_number:
                    return Response({'error': '活动每人最大领取数不得大于活动总数'}, status=status.HTTP_400_BAD_REQUEST)
            if str(max_number_by_user) == '1':
                if not max_number_by_user_count:
                    return Response({'error': '请上传活动每人最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    max_number_by_user_count = int(max_number_by_user_count)
                except:
                    return Response({'error': '活动每人最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                if max_number_by_user_count > max_number:
                    return Response({'error': '活动每人最大领取数不得大于活动总数'}, status=status.HTTP_400_BAD_REQUEST)
            if str(usetime_type) not in ['1', '2', '3', '4']:
                return Response({'error': '优惠券有效期参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            alidiscountcoupon_data = {}
            if str(coupon_way) == '3':
                alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
            alidiscountcoupon_data['user_id'] = user.id
            alidiscountcoupon_data['level_id'] = level.id
            template_id = f'MC{"%03d" % randint(0, 999)}INFLY{"%06d" % randint(0, 999999)}'
            alidiscountcoupon_data['template_id'] = template_id
            alidiscountcoupon_data['activity_name'] = name
            alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
            alidiscountcoupon_data['name'] = name
            alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
            alidiscountcoupon_data['activity_valid_period'] = f"到{publish_end_time.strftime('%Y年%m月%d日')}"
            alidiscountcoupon_data['activity_description'] = activity_description
            alidiscountcoupon_data['publish_start_time'] = publish_start_time
            alidiscountcoupon_data['publish_end_time'] = publish_end_time
            alidiscountcoupon_data['max_number'] = max_number
            alidiscountcoupon_data['remain_number'] = max_number
            alidiscountcoupon_data['max_number_by_day'] = max_number_by_day_count
            alidiscountcoupon_data['max_number_by_user'] = max_number_by_user_count
            alidiscountcoupon_data['coupon_type'] = coupon_type
            alidiscountcoupon_data['coupon_channel'] = 3
            alidiscountcoupon_data['coupon_status'] = 3
            alidiscountcoupon_data['is_need_auth'] = 1
            alidiscountcoupon_data['coupon_way'] = coupon_way
            alidiscountcoupon_data['available_merchants'] = ''
            alidiscountcoupon_data['is_check_identity'] = 0
            alidiscountcouponchannelcommonvoucher_data = {}
            alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = 4
            alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
            alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 0
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = max_number_by_user
            alidiscountcouponchannelcommonvoucher_data['budget_amount'] = 0
            if fn_order_id:
                alidiscountcoupon_data['fn_order_id'] = fn_order_id
            if str(coupon_type) == '6':
                alidiscountcoupon_data['floor_amount'] = '可兑换指定商品一份'
            elif str(coupon_type) == '9':
                if not transaction_minimum:
                    return Response({'error': '满减券请上传使用门槛'}, status=status.HTTP_400_BAD_REQUEST)
                if not amount:
                    return Response({'error': '满减券请设置面额'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    transaction_minimum = Decimal(transaction_minimum)
                except:
                    return Response({'error': '门槛参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    amount = Decimal(amount)
                except:
                    return Response({'error': '面额参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                if amount >= transaction_minimum:
                    return Response({'error': '使用门槛不得小于券面额'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                alidiscountcoupon_data['amount'] = amount
                alidiscountcoupon_data['floor_amount'] = f'满{transaction_minimum}元减{amount}元'

            else:
                return Response({'error': '商家券类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
            alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
            if str(join_limit_by_bay) == '1':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每天最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每天最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            elif str(join_limit_by_bay) == '2':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每周最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每周最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            elif str(join_limit_by_bay) == '3':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每月最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每月最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            else:
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
            if str(usetime_type) == '1':
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = publish_start_time
                alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = publish_end_time
            elif str(usetime_type) == '2':
                try:
                    start_fixed_time = datetime.datetime.strptime(start_fixed_time, '%Y-%m-%d %H:%M:%S')
                    end_fixed_time = datetime.datetime.strptime(end_fixed_time, '%Y-%m-%d %H:%M:%S')
                except:
                    return Response({'error': '优惠券有效时间格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                if end_fixed_time <= datetime.datetime.now():
                    return Response({'error': '优惠券有效时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
                if end_fixed_time <= start_fixed_time:
                    return Response({'error': '优惠券有效时间须大于开始时间'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = start_fixed_time
                alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = end_fixed_time
            elif str(usetime_type) == '3':
                if not invalid_day:
                    return Response({'error': '请上传有效期期限'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    invalid_day = int(invalid_day)
                except:
                    return Response({'error': '有效期期限须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                alidiscountcouponchannelcommonvoucher_data['invalid_day'] = invalid_day
            else:
                if not invalid_day:
                    return Response({'error': '请上传有效期期限'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    invalid_day = int(invalid_day)
                except:
                    return Response({'error': '有效期期限须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 4
                alidiscountcouponchannelcommonvoucher_data['invalid_day'] = invalid_day
            AliDiscountCouponChannelCommonVoucher.objects.get_or_create(defaults=alidiscountcouponchannelcommonvoucher_data, alidiscountcoupon_id=alidiscountcoupon.id)
            AliDiscountCouponOperationRecord.objects.create(
                alidiscountcoupon_id=alidiscountcoupon.id,
                create_user_id=user.id,
                remark='创建活动'
            )
            return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
        elif str(coupon_channel) == '5':
            if not template_id:
                return Response({'error': '美团活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            activity = AliDiscountCoupon.objects.filter(template_id=template_id, coupon_channel=5)
            if activity:
                return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=5).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_meituan_acitivty(template_id, platform)
            if data_dict['status'] == 'fail':
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            if not data_dict['data']:
                return Response({'error': '无效批次号'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['data']['titleShow']
                    transaction_minimum = data_dict['data']['discountDetaiDtos'][0]['quotaValue']
                    coupon_amount = data_dict['data']['discountDetaiDtos'][0]['reduceValue']
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = '中国邮政储蓄储蓄卡'
                    available_begin_time = datetime.datetime.strptime(data_dict['data']['validBeginTime'], "%Y-%m-%d %H:%M:%S")
                    available_end_time = datetime.datetime.strptime(data_dict['data']['assignEndTime'], "%Y-%m-%d %H:%M:%S")
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    alidiscountcoupon_data['activity_description'] = data_dict['data']['restrictShow']
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = int(data_dict['data']['totalCount'])
                    alidiscountcoupon_data['remain_number'] = int(data_dict['data']['totalCount'])
                    max_number_by_user = data_dict['data']['receiveLimitDto']['userReceiveLimit']
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user if max_number_by_user else None
                    alidiscountcoupon_data['coupon_type'] = 2
                    alidiscountcoupon_data['coupon_channel'] = 5
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 0
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        # if data_dict['data']['bankType'] == 0:
                        #     bankcard_type = 4
                        # elif data_dict['data']['dataVO']['form']['bankCardType'] == 'CREDIT':
                        #     bankcard_type = 1
                        # elif data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT_CREDIT':
                        #     bankcard_type = 3
                        # else:
                        bankcard_type = 3
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = bankcard_type
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                        alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['countDownDays']
                        if data_dict['data']['receiveLimitDto']['userReceiveLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = data_dict['data']['receiveLimitDto']['userReceiveLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 2
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = 0

                        if data_dict['data']['receiveLimitDto']['daySendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['daySendLimit']
                        elif data_dict['data']['receiveLimitDto']['weekSendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['weekSendLimit']
                        elif data_dict['data']['receiveLimitDto']['monthSendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['monthSendLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = 0
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = Decimal(data_dict['data']['totalCount']) * Decimal(coupon_amount)
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                    AliDiscountCouponOperationRecord.objects.create(
                        alidiscountcoupon_id=alidiscountcoupon.id,
                        create_user_id=user.id,
                        remark='创建活动'
                    )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': '无效活动类型参数'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        coupon_way = self.request.data.get('coupon_way', None)
        publish_start_time = self.request.data.get('publish_start_time', None)
        publish_end_time = self.request.data.get('publish_end_time', None)
        is_need_auth = self.request.data.get('is_need_auth', None)
        is_white = self.request.data.get('is_white', None)
        is_union = self.request.data.get('is_union', None)
        available_merchants = self.request.data.get('available_merchants', None)
        activity_description = self.request.data.get('activity_description', None)
        max_number = self.request.data.get('max_number', None)
        distributed_limit_by_time = self.request.data.get('distributed_limit_by_time', None)
        distributed_limit_by_time_rules = self.request.data.get('distributed_limit_by_time_rules', [])
        level_id = self.request.data.get('level_id', None)
        remark = self.request.data.get('remark', None)
        distribution_platform_id = self.request.data.get('distribution_platform_id', None)
        drawdown_platform_id = self.request.data.get('drawdown_platform_id', None)
        is_use_path = self.request.data.get('is_use_path', None)
        use_path = self.request.data.get('use_path', None)
        use_appid = self.request.data.get('use_appid', None)
        is_self = self.request.data.get('is_self', None)
        goods_tag = self.request.data.get('goods_tag', None)
        max_number_by_day = self.request.data.get('max_number_by_day', None)
        is_max_number_by_day = self.request.data.get('is_max_number_by_day', None)
        is_check_identity = self.request.data.get('is_check_identity', None)
        banner_short = self.request.FILES.get('banner_short', None)
        banner_long = self.request.FILES.get('banner_long', None)
        is_psbc_card = self.request.data.get('is_psbc_card', None)
        join_limit_by_location = self.request.data.get('join_limit_by_location', None)
        is_keguan = self.request.data.get('is_keguan', '')
        pushEventIds = self.request.data.get('pushEventIds', '')
        bankcard_type = self.request.data.get('bankcard_type', '')
        usage_scenario = self.request.data.get('usage_scenario', '')
        if str(is_keguan) == '1':
            if not pushEventIds:
                return Response({'error': '请上传营销事件ID'}, status=status.HTTP_400_BAD_REQUEST)
            if not instance.level.account_nine:
                return Response({'error': '活动所属机构尚未绑定9位机构号,请联系管理员处理'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_keguan = 1
            instance.pushEventIds = pushEventIds
            keguan_data = {}
            keguan_data['sourceId'] = instance.template_id
            keguan_data['pushEventIds'] = str(pushEventIds).split('|')
            keguan_data['orgNo'] = instance.level.account_nine
            keguan_data['activityName'] = instance.activity_name
            keguan_data['startTime'] = instance.publish_start_time.strftime("%Y-%m-%dT%H:%M:%S.120+08:00")
            keguan_data['endTime'] = instance.publish_end_time.strftime("%Y-%m-%dT%H:%M:%S.120+08:00")
            keguan_result = ylx_api('ThirdActInfoSyncGdCrm', keguan_data)
            if keguan_result['meta']['code'] != 200:
                return Response({'error': f"同步客管系统失败,原因:{keguan_result['meta']['msg']}"}, status=status.HTTP_400_BAD_REQUEST)
            AliDiscountCouponKeguanRecords.objects.create(alidiscountcoupon_id=instance.id, operate_user_id=user.id, operate_type=1)
        elif str(is_keguan) == '0':
            instance.is_keguan = 0
            AliDiscountCouponKeguanRecords.objects.create(alidiscountcoupon_id=instance.id, operate_user_id=user.id, operate_type=2)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                # if str(coupon_way) in ['1', '2', '3']:
                #     instance.coupon_way = coupon_way
                operation_remark = ''
                if publish_start_time and publish_end_time:
                    try:
                        publish_start_time = datetime.datetime.strptime(publish_start_time, "%Y-%m-%d %H:%M:%S")
                        publish_end_time = datetime.datetime.strptime(publish_end_time, "%Y-%m-%d %H:%M:%S")
                    except:
                        return Response({'error': '活动时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                    if publish_start_time >= publish_end_time:
                        return Response({'error': '活动开始时间须大于结束时间!'}, status=status.HTTP_400_BAD_REQUEST)
                    if datetime.datetime.now() >= publish_end_time:
                        return Response({'error': '活动结束时间须大于当前时间!'}, status=status.HTTP_400_BAD_REQUEST)
                    operation_remark += f'修改活动时间,原活动时间:{instance.publish_start_time.strftime("%Y-%m-%d %H:%M:%S")}至{instance.publish_end_time.strftime("%Y-%m-%d %H:%M:%S")};'
                    instance.publish_start_time = publish_start_time
                    instance.publish_end_time = publish_end_time
                    if instance.coupon_status == 2:
                        instance.coupon_status = 3
                if str(is_need_auth) in ['0', '1']:
                    operation_remark += f'修改是否需要认证,原活动:{instance.get_is_need_auth_display()};'
                    instance.is_need_auth = is_need_auth
                if str(is_white) in ['0', '1']:
                    operation_remark += f'修改是否需要白名单校验,原活动:{instance.get_is_white_display()};'
                    instance.is_white = is_white
                if str(is_union) in ['0', '1']:
                    operation_remark += f'修改是否友商联盟,原活动:{instance.get_is_union_display()};'
                    instance.is_union = is_union
                if available_merchants:
                    operation_remark += f'修改参与活动商户说明,原活动:{instance.available_merchants};'
                    instance.available_merchants = available_merchants
                if activity_description:
                    operation_remark += f'修改活动使用说明,原活动:{instance.activity_description};'
                    instance.activity_description = activity_description
                if max_number:
                    try:
                        max_number = int(max_number)
                    except:
                        return Response({'error': '活动最大派发数参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                    operation_remark += f'修改活动总额度,原活动:{instance.max_number};'
                    old_max_number = instance.max_number
                    instance.max_number = max_number
                    instance.remain_number = instance.remain_number + max_number - old_max_number
                if str(join_limit_by_location) in ['2', '1']:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    operation_remark += f'修改活动地理位置参与限制,原活动:{channelcommonvoucher.get_join_limit_by_location_display()};'
                    channelcommonvoucher.join_limit_by_location = join_limit_by_location
                    channelcommonvoucher.save()
                if str(distributed_limit_by_time) in ['1', '2']:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    if str(distributed_limit_by_time) == '1' and channelcommonvoucher.distributed_limit_by_time == 2:
                        if not distributed_limit_by_time_rules:
                            return Response({'error': '请上传固定派发时间规则!'}, status=status.HTTP_400_BAD_REQUEST)
                    channelcommonvoucher.distributed_limit_by_time = distributed_limit_by_time
                    channelcommonvoucher.save()
                    alidiscountcoupondistributedlimit_set = channelcommonvoucher.alidiscountcoupondistributedlimit_set.all().delete()
                    for rule in distributed_limit_by_time_rules:
                        start_enable_time = rule['start_enable_time']
                        end_enable_time = rule['end_enable_time']
                        weeks = rule['weeks']
                        try:
                            start_enable_time = datetime.datetime.strptime(f'1970-01-01 {start_enable_time}', "%Y-%m-%d %H:%M:%S")
                            end_enable_time = datetime.datetime.strptime(f'1970-01-01 {end_enable_time}', "%Y-%m-%d %H:%M:%S")
                        except:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '派发时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                        if start_enable_time >= end_enable_time:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '派发时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                        AliDiscountCouponDistributedLimit.objects.create(
                            ali_discount_coupon_common_voucher_id=channelcommonvoucher.id,
                            start_enable_time=start_enable_time,
                            end_enable_time=end_enable_time,
                            weeks=weeks
                        )
                if bankcard_type:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    channelcommonvoucher.bankcard_type = bankcard_type
                    channelcommonvoucher.save()
                if usage_scenario:
                    instance.usage_scenario = usage_scenario
                if level_id:
                    instance.level_id = level_id
                if str(is_psbc_card) in ['0', '1']:
                    instance.is_psbc_card = int(is_psbc_card)
                if remark:
                    operation_remark += f'修改备注,原活动:{instance.remark};'
                    instance.remark = remark
                if distribution_platform_id:
                    try:
                        distribution_platform = AliDiscountCouponDistributionPlatform.objects.get(id=distribution_platform_id)
                    except:
                        return Response({'error': '无效派发平台参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if instance.distribution_platform:
                        operation_remark += f'修改派发平台,原活动:{instance.distribution_platform.platform_name};'
                    else:
                        operation_remark += f'修改派发平台,原活动:无;'
                    instance.distribution_platform_id = distribution_platform_id
                if drawdown_platform_id:
                    try:
                        drawdown_platform = AliDiscountCouponDistributionPlatform.objects.get(id=drawdown_platform_id)
                    except:
                        return Response({'error': '无效派发平台参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if instance.drawdown_platform_id:
                        operation_remark += f'修改派发平台,原活动:{instance.drawdown_platform.platform_name};'
                    else:
                        operation_remark += f'修改派发平台,原活动:无;'
                    instance.drawdown_platform_id = drawdown_platform_id
                if str(is_use_path) == '1':
                    if not all([use_appid, use_path]):
                        return Response({'error': '请上传跳转参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if str(is_self) not in ['0', '1']:
                        return Response({'error': '跳转平台参数有误'}, status=status.HTTP_400_BAD_REQUEST)
                    instance.is_use_path = is_use_path
                    instance.use_path = use_path
                    instance.use_appid = use_appid
                    instance.is_self = is_self
                if str(is_use_path) == '0':
                    instance.is_use_path = is_use_path
                if goods_tag:
                    instance.goods_tag = goods_tag
                if str(is_max_number_by_day) == '1':
                    instance.max_number_by_day = max_number_by_day
                elif str(is_max_number_by_day) == '0':
                    instance.max_number_by_day = 0
                if str(is_check_identity) == '1':
                    instance.is_check_identity = 1
                elif str(is_check_identity) == '0':
                    instance.is_check_identity = 0
                if banner_short:
                    banner_short_str = banner_short.read()
                    tmpIm = io.BytesIO(banner_short_str)
                    image = Image.open(tmpIm)
                    width, height = image.size
                    if width != 750 or height != 268:
                        return Response({'error': 'banner短图尺寸不符,图片规格要求750*268'}, status=status.HTTP_400_BAD_REQUEST)
                    banner_short_img = pic_upload(banner_short_str, key=None)
                    instance.banner_short = banner_short_img
                if banner_long:
                    banner_long_str = banner_long.read()
                    tmpIm = io.BytesIO(banner_long_str)
                    image = Image.open(tmpIm)
                    width, height = image.size
                    if width != 750 or height != 460:
                        return Response({'error': 'banner长图尺寸不符,图片规格要求750*460'}, status=status.HTTP_400_BAD_REQUEST)
                    banner_long_img = pic_upload(banner_long_str, key=None)
                    instance.banner_long = banner_long_img
                instance.save()
                AliDiscountCouponOperationRecord.objects.create(
                    alidiscountcoupon_id=instance.id,
                    create_user_id=user.id,
                    remark=operation_remark
                )
                transaction.savepoint_commit(save_id)
                return Response({'success': '修改成功!'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update_white_table(self, request):
        activity_id = self.request.data.get('activity_id', None)
        mobile_array = self.request.data.get('mobile_array', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                alidiscountcouponwhitetable_set = instance.alidiscountcouponwhitetable_set.all().delete()
                for mobile in mobile_array:
                    if not re.match(r'^1[3-9]\d{9}$', mobile):
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': f'{mobile}非手机号格式'}, status=status.HTTP_400_BAD_REQUEST)
                    AliDiscountCouponWhiteTable.objects.create(alidiscountcoupon_id=activity_id, mobile=mobile)

                transaction.savepoint_commit(save_id)
                return Response({'success': '修改成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update_merchant(self, request):
        activity_id = self.request.data.get('activity_id', None)
        merchant_array = self.request.data.get('merchant_array', None)
        user = self.request.iser
        if user.platform == 2:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=2, wx_is_enter=1)
        else:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=1, wx_is_enter=1)
        if check_history:
            is_enter = 4
        else:
            is_enter = 1
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(merchant_array, list):
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            updatestockusablemerchant_data = {}
            updatestockusablemerchant_data['user_id'] = user.id
            updatestockusablemerchant_data['test'] = json.dumps(merchant_array)
            updatestockusablemerchant_data['add_type'] = 2
            updatestockusablemerchant_data['alidiscountcoupon_id'] = instance.id
            updatestockusablemerchant_data['wx_is_enter'] = is_enter
            updatestockusablemerchant_data['ylx_is_enter'] = is_enter
            updatestockusablemerchant_data['operation_user_id'] = user.id
            updatestockusablemerchant_data['operation_time'] = datetime.datetime.now()
            history = UpdateStockUsableMerchant.objects.create(**updatestockusablemerchant_data)
            if is_enter == 1:
                update_stock_usable_merchant.delay({'id': history.id})
            # update_stock_usable_merchant({'id': history.id})
            return Response({'success': '提交修改成功,等待系统处理'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        coupon_status = self.request.data.get('coupon_status', None)
        if instance.coupon_status == 2:
            return Response({'error': '活动已结束, 不可操作'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_status) == '1':
            alidiscountcoupon = AliDiscountCouponLevel.objects.filter(activity_id=instance.id)
            if not alidiscountcoupon and instance.coupon_way in [3, 2, 5]:
                alidiscountcoupon_data = {}
                alidiscountcoupon_data['level_id'] = instance.level_id
                alidiscountcoupon_data['activity_id'] = instance.id
                alidiscountcoupon_data['max_number'] = instance.max_number
                alidiscountcoupon_data['remain_number'] = instance.max_number
                alidiscountcoupon_data['p_max_number'] = instance.max_number
                alidiscountcoupon_data['p_remain_number'] = instance.max_number
                identify = random_str(randomlength=64)
                common_url = f'https://api.sutpay.com/customer/coupon/?identify={identify}'
                common_qrcode = f'youhuiquanyi/coupon/{identify}.png'
                common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                alidiscountcoupon_data['common_url'] = common_url
                alidiscountcoupon_data['common_qrcode'] = common_qrcode
                alidiscountcoupon_data['identify'] = identify
                AliDiscountCouponLevel.objects.get_or_create(activity_id=instance.id, level_id=instance.level_id, defaults=alidiscountcoupon_data)
            instance.coupon_status = 1
            instance.save()
            return Response({'success': '开启活动成功'}, status=status.HTTP_200_OK)
        elif str(coupon_status) == '2':
            instance.coupon_status = 4
            instance.save()
            return Response({'success': '暂停活动成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '无效活动状态'}, status=status.HTTP_400_BAD_REQUEST)

    def discountcoupon_join_limit_level(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        if not activity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            activity = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level = activity.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(alidiscountcouponlevel__activity_id=activity_id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def discountcoupon_join_limit_location(self, request):
        activity_id = self.request.data.get('activity_id', None)
        mobile_array = self.request.data.get('mobile_array', None)

    def white_table(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        alidiscountcouponwhitetable_set = instance.alidiscountcouponwhitetable_set.all().values_list('mobile', flat=True)
        return Response({'data': list(alidiscountcouponwhitetable_set)}, status=status.HTTP_200_OK)

    def export_activity_merchant(self, request):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT * FROM (SELECT e.*,f.activity_name,template_id FROM (SELECT c.*,d.prov_name,city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID,level_id FROM (SELECT id,merchant_id,sub_mchid,alidiscountcoupon_id,channel_id FROM tb_ali_discount_coupon_merchant WHERE alidiscountcoupon_id={alidiscountcoupon_id})AS a LEFT JOIN (SELECT short_name,wyfMerchantID,name,id,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN(SELECT id,name AS activity_name,template_id FROM tb_ali_discount_coupon)AS f ON e.alidiscountcoupon_id=f.id)AS g LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS h ON g.channel_id=h.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '活动id', '活动名称', '微信批次号', '微信商户号', '所属通道', '微邮付商户号', '可用商户全称', '可用商户简称', '所属省公司', '所属市公司', '所属区县', '所属网点']
        cols = ['id', 'alidiscountcoupon_id', 'activity_name', 'template_id', 'sub_mchid', 'channel_name', 'wyfMerchantID', 'name', 'short_name', 'prov_name', 'city_name', 'district_name', 'branch_name']
        response = StreamingHttpResponse(self.get_activity_merchant_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_activity_merchant_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def allocation_max_number(self, request):
        user = self.request.iser
        data_array = self.request.data.get('data_array', None)
        activity_id = self.request.data.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level_list = get_level_list(instance.level)
        level_range = instance.level.level
        if instance.coupon_way == 1:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            max_number__sum = instance.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
            if max_number__sum:
                remain_number = instance.max_number - max_number__sum
            else:
                remain_number = instance.max_number
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    queryset_list = []
                    for allot in data_array:
                        if int(allot['level_id']) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        if int(allot['count']) < 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '分配数量须大于0'}, status=status.HTTP_400_BAD_REQUEST)
                        if remain_number < int(allot['count']):
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '分配数据超过活动最大数'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel_data = {}
                        diacountcouponlevel_data['level_id'] = allot['level_id']
                        diacountcouponlevel_data['activity_id'] = activity_id
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=allot['level_id']).first()
                        if diacountcouponlevel and diacountcouponlevel.max_number != 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': f'{diacountcouponlevel.level.name}重复配置'}, status=status.HTTP_400_BAD_REQUEST)
                        if diacountcouponlevel:
                            diacountcouponlevel.max_number += int(allot['count'])
                            diacountcouponlevel.remain_number += int(allot['count'])
                            diacountcouponlevel.p_max_number += int(allot['count'])
                            diacountcouponlevel.p_remain_number += int(allot['count'])
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data['max_number'] = int(allot['count'])
                            diacountcouponlevel_data['remain_number'] = int(allot['count'])
                            diacountcouponlevel_data['p_max_number'] = int(allot['count'])
                            diacountcouponlevel_data['p_remain_number'] = int(allot['count'])
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(defaults=diacountcouponlevel_data, activity_id=activity_id, level_id=allot['level_id'])
                        remain_number -= int(allot['count'])
                        queryset_list.append(diacountcouponlevel.id)
                    level_level_list = []
                    queryset_list1 = []
                    for i in range(4, level_range, -1):
                        level_level_list.append(i)
                        queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list, level__level__in=level_level_list)
                        for query in queryset:
                            query_level = query.level
                            if i == 4:
                                diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 3:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 2:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            else:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 2:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                            if not instance1:
                                instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                            queryset_list1.append(instance1.id)
                            p_max_number = instance1.p_max_number + query.max_number
                            p_remain_number = instance1.p_remain_number + query.remain_number
                            instance1.p_max_number = p_max_number
                            instance1.p_remain_number = p_remain_number
                            instance1.save()
                            relation_data = {
                                "parent_id": instance1.id,
                                "child_id": query.id
                            }
                            AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                    level_level_list = []
                    for i in range(4, level_range, -1):
                        level_level_list.append(i)
                        queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list1, level__level__in=level_level_list)
                        for query in queryset:
                            query_level = query.level
                            if i == 4:
                                diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 3:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 2:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            else:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 2:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                            if not instance1:
                                instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                            queryset_list1.append(instance1.id)
                            relation_data = {
                                "parent_id": instance1.id,
                                "child_id": query.id
                            }
                            AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        elif instance.coupon_way == 4:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    for level_id in data_array:
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=level_id).first()
                        if diacountcouponlevel:
                            diacountcouponlevel.is_auth = 1
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data = {}
                            diacountcouponlevel_data['level_id'] = level_id
                            diacountcouponlevel_data['activity_id'] = activity_id
                            diacountcouponlevel_data['is_auth'] = 1
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(activity_id=activity_id, level_id=level_id, defaults=diacountcouponlevel_data)
                            level_level_list = []
                            queryset_list = []
                            queryset_list.append(diacountcouponlevel.id)
                            for i in range(4, level_range, -1):
                                level_level_list.append(i)
                                queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list, level__level__in=level_level_list)
                                for query in queryset:
                                    query_level = query.level
                                    if i == 4:
                                        diacountcouponlevel_level_id = query_level.parent_id
                                    elif i == 3:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    elif i == 2:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                        elif query_level.level == 3:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    else:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                        elif query_level.level == 3:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                        elif query_level.level == 2:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                                    if not instance1:
                                        instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                                    queryset_list.append(instance1.id)
                                    relation_data = {
                                        "parent_id": instance1.id,
                                        "child_id": query.id
                                    }
                                    AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        elif instance.coupon_way == 7:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    for level_id in data_array:
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=level_id).first()
                        if diacountcouponlevel:
                            diacountcouponlevel.is_auth = 1
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data = {}
                            diacountcouponlevel_data['level_id'] = level_id
                            diacountcouponlevel_data['activity_id'] = activity_id
                            diacountcouponlevel_data['is_auth'] = 1
                            identify = random_str(randomlength=64)
                            if instance.drawdown_platform_id == 3:
                                common_url = f'https://qrcode.sutpay.com/business/coupon/?identify={identify}'
                            else:
                                common_url = f'https://api.sutpay.com/customer/coupon/?identify={identify}'
                            common_qrcode = f'youhuiquanyi/coupon/{identify}.png'
                            common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                            diacountcouponlevel_data['common_url'] = common_url
                            diacountcouponlevel_data['common_qrcode'] = common_qrcode
                            diacountcouponlevel_data['identify'] = identify
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(activity_id=activity_id, level_id=level_id, defaults=diacountcouponlevel_data)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '当前活动类型不允许分配'}, status=status.HTTP_400_BAD_REQUEST)

    def allocation_level(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        if not activity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            activity = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
            if max_number__sum:
                remain_number = activity.max_number - max_number__sum
            else:
                remain_number = activity.max_number
            can_remain_number = remain_number
        except:
            can_remain_number = 0
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['can_remain_number'] = str(can_remain_number)
        level = activity.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(alidiscountcouponlevel__activity_id=activity_id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def sync_use_merchant(self, request):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        if not alidiscountcoupon_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        activity = self.get_queryset().filter(id=alidiscountcoupon_id, coupon_channel=2).first()
        if not activity:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.syn_status == 2:
            return Response({'error': '活动可用商户同步中'}, status=status.HTTP_400_BAD_REQUEST)
        syn_count = AliDiscountCoupon.objects.filter(syn_status=2).count()
        if syn_count > 10:
            return Response({'error': '同步可用商户的活动超过10个'}, status=status.HTTP_400_BAD_REQUEST)
        sync_activity_merchant.delay({'id': activity.id})
        return Response({'success': '同步成功'}, status=status.HTTP_200_OK)

    def bind_developer(self, request):
        user = self.request.iser
        activity_id = self.request.data.get('activity_id', None)
        developer_id = self.request.data.get('developer_id', None)
        product_no = self.request.data.get('product_no', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_way != 5:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            developer = User.objects.get(id=developer_id)
        except:
            return Response({'error': '无效开发者id'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.is_developer != 1:
            return Response({'error': '关联用户尚未成为开发者'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.is_active != 1:
            return Response({'error': '关联用户状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.id == 65449:
            if not product_no:
                return Response({'error': '请上传商品id'}, status=status.HTTP_400_BAD_REQUEST)
            check_activity = AliDiscountCoupon.objects.filter(product_no=product_no)
            if check_activity:
                return Response({'error': '重复商品id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.product_no = product_no
            instance.save()
        data = {}
        data['developer_id'] = developer_id
        data['alidiscountcoupon_id'] = activity_id
        data['create_user_id'] = user.id
        AliDiscountCouponAPIRelation.objects.get_or_create(defaults=data, developer_id=developer_id, alidiscountcoupon_id=activity_id)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def unbind_developer(self, request):
        id = self.request.data.get('id', None)
        if not id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            AliDiscountCouponAPIRelation.objects.filter(id=id).delete()
            return Response({'error': '操作成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '操作失败'}, status=status.HTTP_400_BAD_REQUEST)

    def sync_wyh_data(self, request):
        user = self.request.iser
        activity_id = self.request.data.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_way not in [1, 4, 2, 7]:
            return Response({'error': '仅限员工派券活动'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_channel not in [2]:
            return Response({'error': '仅限微信代金券活动'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.distribution_platform_id not in [5, 6]:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        check_record = AliDiscountCouponSyncWYHRecord.objects.filter(sync_status__in=[1, 2], alidiscountcoupon_id=instance.id)
        if check_record:
            return Response({'error': '活动已在队列中,请勿重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        check_record = AliDiscountCouponSyncWYHRecord.objects.filter(sync_status=1).first()
        if check_record:
            AliDiscountCouponSyncWYHRecord.objects.create(
                alidiscountcoupon_id=instance.id,
                create_user_id=user.id,
                sync_status=2,
            )
        else:
            record = AliDiscountCouponSyncWYHRecord.objects.create(
                alidiscountcoupon_id=instance.id,
                create_user_id=user.id,
                sync_status=1,
            )
            sync_activity_wyh_data.delay({'record_id': record.id})
        return Response({'success': '提交成功,请等待处理'}, status=status.HTTP_200_OK)

    def export_activity(self, request):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        coupon_status = self.request.query_params.get('coupon_status', None)
        coupon_channel = self.request.query_params.get('coupon_channel', None)
        distribution_platform_id = self.request.query_params.get('distribution_platform_id', None)
        publish_time_begin = self.request.query_params.get('publish_time_begin', None)
        publish_time_end = self.request.query_params.get('publish_time_end', None)
        user_id = self.request.query_params.get('user_id', None)
        search = self.request.query_params.get('search', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id!=0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (activity_name LIKE "%{search}%" OR template_id LIKE "%{search}%" )'
        if publish_time_begin:
            condition = condition + f' AND publish_time_begin >= "{publish_time_begin + " 00:00:00"}"'
        if publish_time_end:
            condition = condition + f' AND publish_time_end <= "{publish_time_end + " 23:59:59"}"'
        if coupon_status:
            condition = condition + f' AND coupon_status in ({coupon_status})'
        if coupon_channel:
            condition = condition + f' AND coupon_channel in ({coupon_channel})'
        if distribution_platform_id:
            condition = condition + f' AND distribution_platform_id in ({distribution_platform_id})'
        if user_id:
            condition = condition + f' AND user_id={user_id}'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.platform_name FROM (SELECT c.*,d.name,mchid FROM (SELECT a.*,b.prov_name,city_name,district_name,branch_name FROM (SELECT id,template_id,activity_name,level_id,coupon_status,coupon_way,coupon_type,distribution_platform_id,floor_amount,DATE_FORMAT(publish_start_time,'%Y-%m-%d %H:%i:%S') AS publish_start_time,DATE_FORMAT(publish_end_time,'%Y-%m-%d %H:%i:%S') AS publish_end_time,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,platform_id,amount,send_count,remain_number,max_number,use_count,use_amount FROM tb_ali_discount_coupon {condition})AS a LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,name,mchid FROM tb_channel)AS d ON c.platform_id=d.id)AS e LEFT JOIN (SELECT id,platform_name FROM tb_ali_discount_coupon_distribution_platform)AS f ON e.distribution_platform_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.platform_name FROM (SELECT c.*,d.name,mchid FROM (SELECT a.*,b.prov_name,city_name,district_name,branch_name FROM (SELECT id,template_id,activity_name,level_id,coupon_status,coupon_way,coupon_type,distribution_platform_id,floor_amount,DATE_FORMAT(publish_start_time,'%Y-%m-%d %H:%i:%S') AS publish_start_time,DATE_FORMAT(publish_end_time,'%Y-%m-%d %H:%i:%S') AS publish_end_time,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,platform_id,amount,send_count,remain_number,max_number,use_count,use_amount FROM tb_ali_discount_coupon)AS a LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,name,mchid FROM tb_channel)AS d ON c.platform_id=d.id)AS e LEFT JOIN (SELECT id,platform_name FROM tb_ali_discount_coupon_distribution_platform)AS f ON e.distribution_platform_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['活动id', '微信代金券批次', '活动名称', '活动归属机构(省)', '活动归属机构(市)', '活动归属机构(区)', '派发方式',
                  '活动状态', '派发平台', '优惠规则', '活动时间(起)', '活动时间(止)', '活动创建时间', '配券平台', '优惠券面额',
                  '已派发', '剩余', '总共', '已核销']
        cols = ['id', 'template_id', 'activity_name', 'prov_name', 'city_name', 'district_name',
                'coupon_way', 'coupon_status', 'platform_name', 'floor_amount', 'publish_start_time', 'publish_end_time',
                'create_time', 'mchid', 'amount', 'send_count', 'remain_number', 'max_number', 'use_count']
        response = StreamingHttpResponse(self.get_activity_merchant_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_activity_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        COUPONS_STATUS_ENUM = {
            "1": '进行中',
            "2": '已结束',
            "3": '未开始',
            "4": '已暂停'
        }
        COUPON_WAY_ENUM = {
            "1": '员工派券(固定)',
            "2": '公开派券',
            "3": '限时活动',
            "4": '员工派券(共享)',
            "5": 'API派券',
            "6": '定制活动',
            "7": '公开派券(多码)',
            "8": '公开派券(手机银行)'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'coupon_status':
                    tmp_str += '"%s",' % (COUPONS_STATUS_ENUM[row[col]])
                elif col == 'coupon_way':
                    tmp_str += '"%s",' % (COUPON_WAY_ENUM[row[col]])
                elif col == 'coupon_way':
                    tmp_str += '"%s",' % (COUPON_WAY_ENUM[row[col]])
                elif col in ['send_count', 'remain_number', 'max_number', 'use_count']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else 0)
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def add_coupon_goods(self, request):
        user = self.request.iser
        goods_id_array = self.request.data.get('goods_id_array', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        if not all([goods_id_array, alidiscountcoupon_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if type(goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                for goods_id in goods_id_array:
                    available_data = {}
                    available_data['goods_id'] = goods_id
                    available_data['alidiscountcoupon_id'] = alidiscountcoupon_id
                    AliDiscountCouponGoodsAvailable.objects.get_or_create(defaults=available_data, goods_id=goods_id, alidiscountcoupon_id=alidiscountcoupon_id)
                transaction.savepoint_commit(save_id)
                return Response({'success': '绑定成功'}, status=status.HTTP_200_OK)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '绑定失败'}, status=status.HTTP_400_BAD_REQUEST)

    def coupon_goods(self, request):
        user = self.request.iser
        add_goods_id_array = self.request.data.get('add_goods_id_array', None)
        del_goods_id_array = self.request.data.get('del_goods_id_array', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        if not alidiscountcoupon_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if type(add_goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if type(del_goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                for goods_id in add_goods_id_array:
                    available_data = {}
                    available_data['goods_id'] = goods_id
                    available_data['alidiscountcoupon_id'] = alidiscountcoupon_id
                    AliDiscountCouponGoodsAvailable.objects.get_or_create(defaults=available_data, goods_id=goods_id, alidiscountcoupon_id=alidiscountcoupon_id)
                AliDiscountCouponGoodsAvailable.objects.filter(goods_id__in=del_goods_id_array, alidiscountcoupon_id=alidiscountcoupon_id).delete()
                transaction.savepoint_commit(save_id)
                return Response({'success': '解绑成功'}, status=status.HTTP_200_OK)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '解绑失败'}, status=status.HTTP_400_BAD_REQUEST)

    def submit_ysh(self, request):
        user = self.request.iser
        sourceDistCode_id = self.request.data.get('sourceDistCode_id', None)
        showDistCode = self.request.data.get('showDistCode', None)
        usageType = self.request.data.get('usageType', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        area_array = self.request.data.get('area_array', None)
        environment = self.request.data.get('environment', '1')
        contract_id = self.request.data.get('contract_id', '1')
        if not alidiscountcoupon_id:
            return Response({'error': '请上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            alidiscountcoupon = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        check_ysh_alidiscountcoupon = YSHAliDiscountCoupon.objects.filter(alidiscountcoupon_id=alidiscountcoupon.id)
        if check_ysh_alidiscountcoupon:
            return Response({'error': '不可重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        if alidiscountcoupon.coupon_way != 5:
            return Response({'error': '活动派发方式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if alidiscountcoupon.distribution_platform_id != 7:
            return Response({'error': '活动派发方式不是邮生活'}, status=status.HTTP_400_BAD_REQUEST)
        if not sourceDistCode_id:
            return Response({'error': '请上传卡券来源的行政区划码'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            sourceDistCode = YSHAreaCode.objects.get(id=sourceDistCode_id)
        except:
            return Response({'error': '无效行政编码id'}, status=status.HTTP_400_BAD_REQUEST)
        if not usageType:
            return Response({'error': '请上传卡券使用类型'}, status=status.HTTP_400_BAD_REQUEST)
        if str(usageType) not in ['1', '2']:
            return Response({'error': '卡券使用类型参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            contract = YSHContract.objects.get(id=contract_id)
        except:
            return Response({'error': '无效合同id'}, status=status.HTTP_400_BAD_REQUEST)
        showDistCode_list = []
        showDistCode_str = ''
        if showDistCode:
            if not isinstance(showDistCode, list):
                return Response({'error': '商品地区参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            for showDistCode_id in showDistCode:
                showDist = YSHAreaCode.objects.filter(id=showDistCode_id).first()
                if showDist:
                    showDistCode_list.append(showDist.code)
                    showDistCode_str += f'{showDist.id},'
        area_list = []
        area_str = ''
        if area_array:
            if not isinstance(area_array, list):
                return Response({'error': '商品地区参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            for area_id in area_array:
                area = YSHAreaCode.objects.filter(id=area_id).first()
                if area:
                    area_list.append({
                        "province": area.prov_name if area.prov_name else "",
                        "city": area.city_name if area.city_name else "",
                        "district": area.district_name if area.district_name else "",
                        "adcode": area.code
                    })
                    area_str += f'{area.id},'
        equityId = f'{alidiscountcoupon.template_id}_WYH_{sourceDistCode.code}'
        name = alidiscountcoupon.activity_name
        type = 'VOUCHER'
        startedAt = alidiscountcoupon.publish_start_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
        endedAt = alidiscountcoupon.publish_end_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
        logo = 'https://ea.sutpay.com/favicon.ico'
        desc = alidiscountcoupon.activity_description
        source = 'WYH'
        verifyChannel = YSHAliDiscountCoupon.VERIFY_CHANNEL_ENUM[alidiscountcoupon.coupon_channel]
        inventory = alidiscountcoupon.remain_number
        totalInventory = alidiscountcoupon.max_number
        couponAmount = int(alidiscountcoupon.amount * 100)
        transactionMinimum = int(alidiscountcoupon.transaction_minimum * 100)
        costAmount = int(Decimal(str(couponAmount*(Decimal('1')+Decimal(str(contract.taxRate/100))))).quantize(Decimal('0')))
        maxCouponsPerUser = alidiscountcoupon.max_number_by_user
        identify = random_str(32)
        mchUrl = f'https://yshmer.sutpay.com/#/?identify={identify}'
        timestamp = str(int(time.time()))
        method = 'saveEquityInfo'
        if str(environment) == '2':
            url = 'http://211.156.216.240:8086/zxyw_uat'
            accessKey = 'f05dba56b4ce41939cd4737d2793752d'
            secretKey = 'Km9t1dW5QZT/hL3ohTIqcoGW2Ok='
        else:
            url = 'http://211.156.195.141:8086/zxyw_sc'
            accessKey = '6a69bf6dbf104e43966204b9fb533747'
            secretKey = 'CAz0q5SXM+DyYxz73yBLIHgu3vM='
        body = {}
        paramJson = {}
        voucher = {}
        paramJson['equityId'] = equityId
        paramJson['name'] = name
        paramJson['type'] = type
        voucher['name'] = name
        voucher['couponAmount'] = couponAmount
        voucher['transactionMinimum'] = transactionMinimum
        voucher['maxCouponsPerUser'] = maxCouponsPerUser
        voucher['mchUrl'] = mchUrl
        voucher['costAmount'] = costAmount
        voucher['supplierCode'] = contract.supplierCode
        voucher['supplierName'] = contract.supplierName
        voucher['contractCode'] = contract.contractCode
        voucher['contractName'] = contract.contractName
        voucher['taxRate'] = float(contract.taxRate/100)
        paramJson['voucher'] = voucher
        paramJson['startedAt'] = startedAt
        paramJson['area'] = area_list
        paramJson['endedAt'] = endedAt
        paramJson['logo'] = {"url": logo}
        paramJson['desc'] = desc
        paramJson['source'] = source
        paramJson['inventory'] = inventory
        paramJson['totalInventory'] = totalInventory
        paramJson['sourceDistCode'] = sourceDistCode.code
        paramJson['showDistCode'] = showDistCode_list
        paramJson['usageType'] = YSHAliDiscountCoupon.VERIFY_CHANNEL_ENUM[int(usageType)]
        paramJson['verifyChannel'] = verifyChannel
        body['paramJson'] = paramJson
        headers = {
            '_api_access_key': accessKey,
            '_api_name': method,
            '_api_timestamp': str(timestamp),
            '_api_version': '1.0.0'
        }
        sign = get_sign_HMACSHA1(headers, secretKey)
        headers['_api_signature'] = sign
        headers['Content-Type'] = 'application/json'
        headers['User-Agent'] = 'PostmanRuntime/7.28.2'
        response = requests.post(url=url, headers=headers, data=json.dumps(body))
        result = response.json()
        logger.info(str(result))
        data = json.loads(result['body'])
        if data['retCode'] == '100001':
            ysh_alidiscountcoupon_data = {}
            ysh_alidiscountcoupon_data['alidiscountcoupon_id'] = alidiscountcoupon.id
            ysh_alidiscountcoupon_data['equityId'] = equityId
            ysh_alidiscountcoupon_data['name'] = name
            ysh_alidiscountcoupon_data['type'] = 1
            ysh_alidiscountcoupon_data['startedAt'] = alidiscountcoupon.publish_start_time
            ysh_alidiscountcoupon_data['endedAt'] = alidiscountcoupon.publish_end_time
            ysh_alidiscountcoupon_data['inventory'] = inventory
            ysh_alidiscountcoupon_data['totalInventory'] = totalInventory
            ysh_alidiscountcoupon_data['couponAmount'] = couponAmount
            ysh_alidiscountcoupon_data['transactionMinimum'] = transactionMinimum
            ysh_alidiscountcoupon_data['mchUrl'] = mchUrl
            ysh_alidiscountcoupon_data['maxCouponsPerUser'] = maxCouponsPerUser
            ysh_alidiscountcoupon_data['sourceDistCode_id'] = sourceDistCode.id
            ysh_alidiscountcoupon_data['showDistCode'] = showDistCode_str[:-1]
            ysh_alidiscountcoupon_data['usageType'] = usageType
            ysh_alidiscountcoupon_data['verifyChannel'] = alidiscountcoupon.coupon_channel
            ysh_alidiscountcoupon_data['serialNo'] = data['serialNo']
            ysh_alidiscountcoupon_data['user_id'] = user.id
            ysh_alidiscountcoupon_data['create_time'] = datetime.datetime.now()
            ysh_alidiscountcoupon_data['identify'] = identify
            ysh_alidiscountcoupon_data['area'] = area_str[:-1]
            ysh_alidiscountcoupon_data['environment'] = environment
            ysh_alidiscountcoupon_data['contract_id'] = contract.id
            ysh_alidiscountcoupon_data['costAmount'] = costAmount
            YSHAliDiscountCoupon.objects.get_or_create(defaults=ysh_alidiscountcoupon_data, alidiscountcoupon_id=alidiscountcoupon.id)
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '操作失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def add_stock_mchid(self, request):
        user = self.request.iser
        if user.platform == 2:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=2, wx_is_enter=1)
        else:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=1, wx_is_enter=1)
        if check_history:
            is_enter = 4
        else:
            is_enter = 1
        my_file = self.request.FILES.get('my_file', None)
        is_black = self.request.data.get('is_black', 1)
        user = self.request.iser
        if not my_file:
            return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        type_excel = my_file.name.split('.')[-1]
        file_contents = my_file.read()
        if type_excel not in ['xlsx', 'xls']:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
        except:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        table = wb.sheets()[0]
        nrows = table.nrows
        if nrows > 10000:
            return Response({'error': '文件数量超过10000,请拆分多份上传'}, status=status.HTTP_400_BAD_REQUEST)
        title = table.row_values(0)
        if '批次号' not in title:
            return Response({'error': '表格字段缺少"批次号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '商户号' not in title:
            return Response({'error': '表格字段缺少"商户号"'}, status=status.HTTP_400_BAD_REQUEST)
        file_name = f'{my_file.name.replace(type_excel, "").replace(".", "")}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.{type_excel}'
        file = pic_upload(file_contents, file_name)
        history = UpdateStockUsableMerchant.objects.create(user_id=user.id, file=file, is_black=is_black, wx_is_enter=is_enter, ylx_is_enter=is_enter,
                                                           operation_user_id=user.id, operation_time=datetime.datetime.now())
        if is_enter == 1:
            update_stock_usable_merchant.delay({'id': history.id})
        # update_stock_usable_merchant({'id': history.id})
        return Response({'success': '上传文件成功'}, status=status.HTTP_200_OK)

class AliCouponDataKeguanModelViewSet(ModelViewSet):
    '''代金券-客管记录'''
    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = AliCouponKeguanFilter
    search_fields = ('alidiscountcouponinfo__out_biz_order',)

    def get_queryset(self):
        queryset = AliDiscountCouponInfoKeguan.objects.all()
        return queryset.order_by('-id')

    def get_serializer_class(self):
        return AliDiscountCouponKeGuanListModelSerializer



class AliDiscountCouponLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    search_fields = ('level__name', )
    filter_class = AliDiscountCouponLevelFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        sort = self.request.query_params.get('sort', '0')
        # activity_id = self.request.query_params.get('activity_id', None)
        # if activity_id:
        #     try:
        #         activity = AliDiscountCoupon.objects.get(id=activity_id)
        #         max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
        #         if max_number__sum:
        #             remain_number = activity.max_number - max_number__sum
        #         else:
        #             remain_number = activity.max_number
        #         if '_mutable' in self.request.data.__dict__:
        #             self.request.data.__dict__['_mutable'] = True
        #         self.request.data['can_remain_number'] = str(remain_number)
        #     except:
        #         pass
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = AliDiscountCouponLevel.objects.all()
        elif level.level == 1:
            queryset = AliDiscountCouponLevel.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = AliDiscountCouponLevel.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = AliDiscountCouponLevel.objects.filter(level__district_id=level.id)
        else:
            queryset = AliDiscountCouponLevel.objects.filter(level__branch_id=level.id)
        if sort == '0':
            queryset = queryset.order_by('max_number', 'id')
        elif sort == '1':
            queryset = queryset.order_by('-max_number', 'id')
        elif sort == '2':
            queryset = queryset.order_by('take_number', 'id')
        elif sort == '3':
            queryset = queryset.order_by('-take_number', 'id')
        elif sort == '4':
            queryset = queryset.order_by('remain_number', 'id')
        elif sort == '5':
            queryset = queryset.order_by('-remain_number', 'id')
        elif sort == '6':
            queryset = queryset.order_by(F('take_number') - F('receive_number'), 'id')
        elif sort == '7':
            queryset = queryset.order_by(-(F('take_number') - F('receive_number')), 'id')
        elif sort == '8':
            queryset = queryset.order_by(F('receive_number') - F('use_number'), 'id')
        elif sort == '9':
            queryset = queryset.order_by(-(F('receive_number') - F('use_number')), 'id')
        elif sort == '10':
            queryset = queryset.order_by('use_number', 'id')
        elif sort == '11':
            queryset = queryset.order_by('-use_number', 'id')
        else:
            queryset = queryset.order_by('level__level', 'id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponLevelListModelSerializer
        else:
            return AliDiscountCouponLevelRetrieveModelSerializer

    def up_file(self, request):
        my_file = self.request.FILES.get('my_file', None)

    def export_couponlevel(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        user = self.request.iser
        if not search:
            if user.level.level == 0:
                condition = ''
            elif user.level.level == 1:
                condition = f'WHERE prov_id={user.id}'
            elif user.level.level == 2:
                condition = f'WHERE city_id={user.id}'
            elif user.level.level == 3:
                condition = f'WHERE district_id={user.id}'
            else:
                condition = f'WHERE branch_id={user.id}'
        else:
            if user.level.level == 0:
                condition = f'WHERE name LIKE "%{search}%"'
            elif user.level.level == 1:
                condition = f'WHERE prov_id={user.id} AND name LIKE "%{search}%"'
            elif user.level.level == 2:
                condition = f'WHERE city_id={user.id} AND name LIKE "%{search}%"'
            elif user.level.level == 3:
                condition = f'WHERE district_id={user.id} AND name LIKE "%{search}%"'
            else:
                condition = f'WHERE branch_id={user.id} AND name LIKE "%{search}%"'
        if not activity_id:
            condition1 = ''
        else:
            condition1 = f'AND activity_id="{activity_id}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT c.*,d.activity_name FROM (SELECT a.*,b.name,account,prov_name,city_name,district_name,branch_name FROM (SELECT id,activity_id,max_number,take_number,remain_number,receive_number,use_number,level_id,(take_number-receive_number)AS unclaimed_number,(receive_number-use_number)AS wait_number FROM tb_ali_discount_coupon_level WHERE max_number!=0 AND level_id IN (SELECT id FROM tb_u_level {condition}) {condition1})AS a LEFT JOIN (SELECT id,name,account,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS d ON c.activity_id=d.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '活动名称', '机构名称', '机构号', '省', '市', '区县', '网点', '总额度', '已派发额度', '剩余额度', '待领取', '待核销', '已核销']
        cols = ['id', 'activity_name', 'name', 'account', 'prov_name', 'city_name', 'district_name', 'branch_name', 'max_number', 'take_number', 'remain_number', 'unclaimed_number',
                'wait_number', 'use_number']
        response = StreamingHttpResponse(self.get_couponlevel_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('支付宝代金券机构领用汇总.csv'))
        return response

    def get_couponlevel_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                # if col == 'unclaimed_number':
                #     tmp_str += '"%s",' % (row['take_number']-row['receive_number'])
                # elif col == 'wait_number':
                #     tmp_str += '"%s",' % (row['receive_number']-row['use_number'])
                if col in ['max_number', 'take_number', 'remain_number', 'unclaimed_number', 'wait_number', 'use_number']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else 0)
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def batch_update_max_number(self, request):
        data_array = self.request.data.get('data_array', None)
        if not data_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(data_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                for data in data_array:
                    instance = AliDiscountCouponLevel.objects.get(id=data['id'])

                    count = -int(data['count'])
                    if count < 0 and instance.remain_number < abs(count):
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': f'{instance.id}剩余数量不足扣减'}, status=status.HTTP_400_BAD_REQUEST)
                    activity = instance.activity
                    instance.max_number = instance.max_number + count
                    instance.remain_number = instance.remain_number + count
                    instance.p_max_number = instance.p_max_number + count
                    instance.p_remain_number = instance.p_remain_number + count
                    instance.save()
                    activity.max_number += count
                    activity.remain_number += count
                    activity.save()
                    relation_set = instance.child_set.all()
                    for relation in relation_set:
                        parent = relation.parent
                        parent.p_max_number += count
                        parent.p_remain_number += count
                        parent.save()
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败'}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        max_number = self.request.data.get('max_number', None)
        try:
            max_number = int(max_number)
        except:
            return Response({'error': '请输入整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.coupon_way != 1:
            return Response({'error': '仅员工派券活动可调整派发额度'}, status=status.HTTP_400_BAD_REQUEST)
        # if instance.max_number <= 0:
        #     return Response({'error': '机构活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
        instance_id = instance.id
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                while True:
                    instance = AliDiscountCouponLevel.objects.get(id=instance_id)
                    count = max_number - instance.max_number
                    if count > 0:
                        max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
                        if max_number__sum:
                            remain_number = activity.max_number - max_number__sum
                        else:
                            remain_number = activity.max_number
                        if remain_number < count:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    else:
                        if instance.remain_number < -count:
                            return Response({'error': '机构活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    origin_remain_number = instance.remain_number
                    origin_max_number = instance.max_number
                    origin_p_remain_number = instance.p_remain_number
                    origin_p_max_number = instance.p_max_number
                    new_remain_number = origin_remain_number + count
                    new_max_number = origin_max_number + count
                    new_p_remain_number = origin_p_remain_number + count
                    new_p_max_number = origin_p_max_number + count
                    result = AliDiscountCouponLevel.objects.filter(id=instance_id, remain_number=origin_remain_number).update(
                        max_number=new_max_number,
                        remain_number=new_remain_number,
                        p_max_number=new_p_max_number,
                        p_remain_number=new_p_remain_number
                    )
                    if result == 0:
                        continue
                    break
                relation_set = instance.child_set.all()
                for relation in relation_set:
                    parent = relation.parent
                    parent.p_max_number += count
                    parent.p_remain_number += count
                    parent.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '调配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '调配成功'}, status=status.HTTP_200_OK)

    def transfer_max_number(self, request):
        count = self.request.data.get('count', None)
        in_id = self.request.data.get('in_id', None)
        out_id = self.request.data.get('out_id', None)
        try:
            count = int(count)
        except:
            return Response({'error': '请输入整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        if count <= 0:
            return Response({'error': '请输入正整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        queryset = self.get_queryset()
        try:
            in_instance = queryset.get(id=in_id)
        except:
            return Response({'error': '无效转入id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            out_instance = queryset.get(id=out_id)
        except:
            return Response({'error': '无效转出id'}, status=status.HTTP_400_BAD_REQUEST)
        if in_instance.activity_id != out_instance.activity_id:
            return Response({'error': '不同活动之间不允许转让'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                while True:
                    in_instance = queryset.get(id=in_id)
                    out_instance = queryset.get(id=out_id)
                    if out_instance.remain_number < count:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '转出机构额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    in_origin_remain_number = in_instance.remain_number
                    in_origin_max_number = in_instance.max_number
                    in_origin_p_remain_number = in_instance.p_remain_number
                    in_origin_p_max_number = in_instance.p_max_number
                    in_new_remain_number = in_origin_remain_number + count
                    in_new_max_number = in_origin_max_number + count
                    in_new_p_remain_number = in_origin_p_remain_number + count
                    in_new_p_max_number = in_origin_p_max_number + count
                    in_result = AliDiscountCouponLevel.objects.filter(id=in_id, remain_number=in_origin_remain_number).update(
                        max_number=in_new_max_number,
                        remain_number=in_new_remain_number,
                        p_max_number=in_new_p_max_number,
                        p_remain_number=in_new_p_remain_number
                    )
                    out_origin_remain_number = out_instance.remain_number
                    out_origin_max_number = out_instance.max_number
                    out_origin_p_remain_number = out_instance.p_remain_number
                    out_origin_p_max_number = out_instance.p_max_number
                    out_new_remain_number = out_origin_remain_number - count
                    out_new_max_number = out_origin_max_number - count
                    out_new_p_remain_number = out_origin_p_remain_number - count
                    out_new_p_max_number = out_origin_p_max_number - count
                    out_result = AliDiscountCouponLevel.objects.filter(id=out_id, remain_number=out_origin_remain_number).update(
                        max_number=out_new_max_number,
                        remain_number=out_new_remain_number,
                        p_max_number=out_new_p_max_number,
                        p_remain_number=out_new_p_remain_number
                    )
                    if in_result == 0 or out_result == 0:
                        continue
                    break
                in_relation_set = in_instance.child_set.all()
                for relation in in_relation_set:
                    parent = relation.parent
                    parent.p_max_number += count
                    parent.p_remain_number += count
                    parent.save()
                out_relation_set = out_instance.child_set.all()
                for relation in out_relation_set:
                    parent = relation.parent
                    parent.p_max_number -= count
                    parent.p_remain_number -= count
                    parent.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '转让失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '转让成功'}, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.p_take_number != 0:
            return Response({'error': '已派发额度,不可删除'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.coupon_way in [1, 2, 3]:
            relation_set = instance.child_set.all()
            for relation in relation_set:
                parent = relation.parent
                parent.p_max_number -= instance.max_number
                parent.p_remain_number -= instance.p_remain_number
                parent.save()
                if parent.p_max_number == Decimal(0):
                    parent.delete()
            relation_set = instance.parent_set.all()
            for relation in relation_set:
                relation.delete()
                child = relation.child
                child.delete()
        instance.delete()
        return Response({'success': '撤销成功'}, status=status.HTTP_200_OK)

    def alidiscountcouponlevel_tree(self, requset):
        activity_id = self.request.query_params.get('activity_id', None)
        if not activity_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        instance = self.get_queryset().filter(activity_id=activity_id).order_by('level__level').first()
        if not instance:
            return Response({}, status=status.HTTP_200_OK)
        serializer = AliDiscountCouponLevelTreeModelSerializer(instance)
        return Response(serializer.data, status=status.HTTP_200_OK)


class AliDiscountCouponMerchantTableHistoryModelViewSet(ModelViewSet):

    queryset = AliDiscountCouponMerchantTableHistory.objects.all().order_by('-id')
    pagination_class = MyPage
    serializer_class = AliDiscountCouponMerchantTableHistoryModelSerializer
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = AliDiscountCouponMerchantTableHistoryFilter

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        my_file = self.request.FILES.get('my_file', None)
        add_type = self.request.data.get('add_type', None)
        data_type = self.request.data.get('data_type', None)
        table_type = self.request.data.get('table_type', None)
        business_list = self.request.data.get('business_list', None)
        if not all([add_type, data_type, table_type]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(add_type) not in ['1', '2']:
            return Response({'error': '无效添加类型参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(table_type) not in ['1', '2']:
            return Response({'error': '无效名单类型参数'}, status=status.HTTP_400_BAD_REQUEST)
        data = {}
        data['create_user_id'] = user.id
        data['add_type'] = add_type
        data['table_type'] = table_type
        data['data_type'] = data_type
        data['add_state'] = 1
        if str(data_type) == '1':
            if not my_file:
                return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
            type_excel = my_file.name.split('.')[-1]
            file_contents = my_file.read()
            if type_excel not in ['xlsx', 'xls']:
                return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
            except:
                return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
            table = wb.sheets()[0]
            nrows = table.nrows
            if nrows > 10000:
                return Response({'error': '文件数量超过10000,请拆分多份上传'}, status=status.HTTP_400_BAD_REQUEST)
            title = table.row_values(0)
            if '商户号' not in title:
                return Response({'error': '表格字段缺少"商户号"'}, status=status.HTTP_400_BAD_REQUEST)
            file_name = f'{my_file.name.replace(type_excel, "").replace(".", "")}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.{type_excel}'
            file = pic_upload(file_contents, file_name)
            data['file'] = file
        elif str(data_type) == '2':
            if not business_list:
                return Response({'error': '请上传商户号列表'}, status=status.HTTP_400_BAD_REQUEST)
            if type(business_list) != list:
                return Response({'error': '商户号数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            data['business_list'] = json.dumps(business_list)
        else:
            return Response({'error': '无效数据类型参数'}, status=status.HTTP_400_BAD_REQUEST)
        history = AliDiscountCouponMerchantTableHistory.objects.create(**data)
        check_history = AliDiscountCouponMerchantTableHistory.objects.filter(add_state=2)
        if not check_history:
            update_stock_merchant_table.delay({'id': history.id})
        return Response({'success': '上传成功'}, status=status.HTTP_200_OK)


class AliDiscountCouponMerchantTableModelViewSet(ModelViewSet):

    queryset = AliDiscountCouponMerchantTable.objects.all().order_by('-id')
    pagination_class = MyPage
    serializer_class = AliDiscountCouponMerchantTableModelSerializer
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = AliDiscountCouponMerchantTableFilter

    def destroy(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        table_type = self.request.data.get('table_type', None)
        if str(table_type) not in ['1', '2']:
            return Response({'error': '无效名单类型参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(table_type) == '1':
            instance.is_white = 0
        else:
            instance.is_black = 0
        instance.save()
        data = {}
        data['create_user_id'] = user.id
        data['add_type'] = 3
        data['table_type'] = table_type
        data['data_type'] = 2
        data['add_state'] = 3
        data['business_list'] = json.dumps([instance.sub_mchid])
        history = AliDiscountCouponMerchantTableHistory.objects.create(**data)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def clear_stock_merchanttable(self, request):
        user = self.request.iser
        table_type = self.request.data.get('table_type', None)
        if str(table_type) not in ['1', '2']:
            return Response({'error': '无效名单类型参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(table_type) == '1':
            business_list = list(AliDiscountCouponMerchantTable.objects.filter(is_white=1).values_list('sub_mchid', flat=True))
            AliDiscountCouponMerchantTable.objects.filter(is_white=1).update(is_white=0)
        else:
            business_list = list(AliDiscountCouponMerchantTable.objects.filter(is_black=1).values_list('sub_mchid', flat=True))
            AliDiscountCouponMerchantTable.objects.filter(is_black=1).update(is_black=0)
        data = {}
        data['create_user_id'] = user.id
        data['add_type'] = 3
        data['table_type'] = table_type
        data['data_type'] = 2
        data['add_state'] = 3
        data['business_list'] = json.dumps(business_list)
        history = AliDiscountCouponMerchantTableHistory.objects.create(**data)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class BlackTableModelViewSet(ModelViewSet):

    queryset = BlackTable.objects.all().order_by('-id')
    pagination_class = MyPage
    serializer_class = BlackTableModelSerializer

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        stock_id_arr = self.request.data.get('stock_id_arr', None)
        for stock_id in stock_id_arr:
            BlackTable.objects.get_or_create(stock_id=stock_id, defaults={"stock_id": stock_id, "create_user_id": user.id})
        return Response({'success': '添加成功'}, status=status.HTTP_200_OK)


class AliDiscountCouponGoodsAvailableModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = AliDiscountCouponGoodsAvailableFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('goods__name', )
    queryset = AliDiscountCouponGoodsAvailable.objects.all().order_by('-goods__sort')

    def get_serializer_class(self):
        return AliDiscountCouponGoodsAvailableListModelSerializer


class AliDiscountCouponDistributionPlatformModelViewSet(ModelViewSet):

    queryset = AliDiscountCouponDistributionPlatform.objects.filter(is_visible=1)
    serializer_class = AliDiscountCouponDistributionPlatformModelSerializer


class AliDiscountCouponSyncWYHRecordModelViewSet(ModelViewSet):

    queryset = AliDiscountCouponSyncWYHRecord.objects.all().order_by('-id')
    serializer_class = AliDiscountCouponSyncWYHRecordModelSerializer
    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__wyfMerchantID', 'sn')
    filter_class = AliDiscountCouponSyncWYHRecordFilter


class CustomizeActivityFlipCARDSModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('user__mobile', 'customeruservice__mobile')
    filter_class = CustomizeActivityFlipCARDSFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = CustomizeActivityFlipCARDS.objects.all()
        elif level.level == 1:
            queryset = CustomizeActivityFlipCARDS.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = CustomizeActivityFlipCARDS.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = CustomizeActivityFlipCARDS.objects.filter(level__district_id=level.id)
        else:
            queryset = CustomizeActivityFlipCARDS.objects.filter(level__branch_id=level.id)
        queryset = queryset.order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return CustomizeActivityFlipCARDSListModelSerializer
        else:
            return CustomizeActivityFlipCARDSRetrieveModelSerializer

    def export_customizeactivityflipcards(self, request):
        user = self.request.iser
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        level_id = self.request.query_params.get('level', None)
        open_status = self.request.query_params.get('open_status', None)
        search = self.request.query_params.get('search', None)
        received_time_begin = self.request.query_params.get('received_time_begin', None)
        received_time_end = self.request.query_params.get('received_time_end', None)
        level = user.level
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE open_status IN (2,4,6)'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id}) AND open_status IN (2,4,6)'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id}) AND open_status IN (2,4,6)'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id}) AND open_status IN (2,4,6)'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id}) AND open_status IN (2,4,6)'
        if search:
            condition = condition + f' AND mobile LIKE "%{search}%"'
        if open_status:
            condition = condition + f' AND open_status IN ({open_status})'
        if customizeactivity_id:
            condition = condition + f' AND customizeactivity_id={customizeactivity_id}'
        if received_time_begin:
            condition = condition + f' AND received_time >= "{received_time_begin + " 00:00:00"}"'
        if received_time_end:
            condition = condition + f' AND received_time <= "{received_time_end + " 23:59:59"}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT k.*,l.business_name,business_type,business_amount,business_account FROM (SELECT i.*,j.c_activity_name FROM (SELECT g.*,h.c_amount,mchid FROM (SELECT e.*,f.v_activity_name,v_floor_amount,v_amount FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.activity_name FROM (SELECT id,open_status,DATE_FORMAT(open_time,'%Y-%m-%d %H:%i:%S')AS open_time,DATE_FORMAT(received_time,'%Y-%m-%d %H:%i:%S')AS received_time,level_id,win_type,alidiscountcoupon_id,cashactivitydata_id,cashactivity_id,mobile,customizeactivity_id FROM tb_customize_activity_flip_cards {condition})AS a LEFT JOIN (SELECT id,activity_name FROM tb_customize_activity)AS b ON a.customizeactivity_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,activity_name AS v_activity_name,floor_amount AS v_floor_amount,amount AS v_amount FROM tb_ali_discount_coupon)AS f ON e.alidiscountcoupon_id=f.id)AS g LEFT JOIN (SELECT id,amount AS c_amount,mchid FROM tb_cash_activity_data)AS h ON g.cashactivitydata_id=h.id)AS i LEFT JOIN (SELECT id,name AS c_activity_name FROM tb_cash_activity)AS j ON i.cashactivity_id=j.id)AS k LEFT JOIN (SELECT customizeactivityflipcards_id,business_name,business_type,business_amount,business_account FROM tb_customize_activity_business_form)AS l ON k.id=l.customizeactivityflipcards_id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT k.*,l.business_name,business_type,business_amount,business_account FROM (SELECT i.*,j.c_activity_name FROM (SELECT g.*,h.c_amount,mchid FROM (SELECT e.*,f.v_activity_name,v_floor_amount,v_amount FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.activity_name FROM (SELECT id,open_status,DATE_FORMAT(open_time,'%Y-%m-%d %H:%i:%S')AS open_time,DATE_FORMAT(received_time,'%Y-%m-%d %H:%i:%S')AS received_time,level_id,win_type,alidiscountcoupon_id,cashactivitydata_id,cashactivity_id,mobile,customizeactivity_id FROM tb_customize_activity_flip_cards)AS a LEFT JOIN (SELECT id,activity_name FROM tb_customize_activity)AS b ON a.customizeactivity_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,activity_name AS v_activity_name,floor_amount AS v_floor_amount,amount AS v_amount FROM tb_ali_discount_coupon)AS f ON e.alidiscountcoupon_id=f.id)AS g LEFT JOIN (SELECT id,amount AS c_amount,mchid FROM tb_cash_activity_data)AS h ON g.cashactivitydata_id=h.id)AS i LEFT JOIN (SELECT id,name AS c_activity_name FROM tb_cash_activity)AS j ON i.cashactivity_id=j.id)AS k LEFT JOIN (SELECT customizeactivityflipcards_id,business_name,business_type,business_amount,business_account FROM tb_customize_activity_business_form)AS l ON k.id=l.customizeactivityflipcards_id;
            '''
            cursor.execute(sql)
        ziduan = ['ID', '活动名称', '手机号', '抽奖时间', '领奖时间', '奖品类型', '奖品状态', '奖品活动名称', '金额', '门槛', '市公司', '区公司', '网点', '业务姓名', '业务账号', '业务金额', '业务类型']
        cols = ['id', 'activity_name', 'mobile', 'open_time', 'received_time', 'win_type', 'open_status', 'v_activity_name', 'v_amount', 'v_floor_amount', 'city_name', 'district_name', 'branch_name', 'business_name', 'business_account', 'business_amount', 'business_type']
        response = StreamingHttpResponse(self.get_customizeactivityflipcards_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('定制活动抽奖明细.csv'))
        return response

    def get_customizeactivityflipcards_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        TRADE_TYPE_ENUM = {
            1: '支付宝',
            2: '微信',
            3: '云闪付'
        }
        IS_HIT_ENUM = {
            0: '未命中',
            1: '已命中'
        }
        WIN_TYPE_ENUM = {
            1: "支付宝代金券",
            2: "微信代金券",
            3: "微信鼓励金",
            4: "谢谢参与",
            5: "积分",
            6: "支付宝鼓励金",
        }
        OPEN_STATUS_ENUM = {
            1: "初始状态",
            2: "待领取",
            3: "谢谢参与",
            4: "已领取",
            5: "失效状态",
            6: "领取失败",
        }
        BUSINESS_TYPE_ENUM = {
            1: "定期",
            2: "活期",
            3: "长期期缴"
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'win_type':
                    tmp_str += '"%s",' % (WIN_TYPE_ENUM[row[col]])
                elif col == 'open_status':
                    tmp_str += '"%s",' % (OPEN_STATUS_ENUM[row[col]])
                elif col == 'business_type':
                    try:
                        tmp_str += '"%s",' % (BUSINESS_TYPE_ENUM[row[col]])
                    except:
                        tmp_str += '"%s",' % ('')
                elif col == 'v_activity_name':
                    if row['win_type'] in [1, 2]:
                        tmp_str += '"%s",' % (row['v_activity_name'])
                    else:
                        tmp_str += '"%s",' % (row['c_activity_name'])
                elif col == 'v_amount':
                    if row['win_type'] in [1, 2]:
                        tmp_str += '"%s",' % (row['v_amount'])
                    else:
                        tmp_str += '"%s",' % (row['c_amount'])
                # elif col == 'amount':
                #     if row['payment_state'] in [1, 2, 3]:
                #         tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                #     else:
                #         tmp_str += '"%s",' % ''
                # elif col in ['order_no', 'trade_no']:
                #     tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class UpdateStockUsableMerchantModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = UpdateStockUsableMerchantFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('customer_user__mobile', )
    queryset = UpdateStockUsableMerchant.objects.exclude(add_type=3).order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return UpdateStockUsableMerchantListModelSerializer
        else:
            return UpdateStockUsableMerchantRetrieveModelSerializer

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        apply_state = str(self.request.data.get('apply_state', None))
        return_msg = self.request.data.get('return_msg', None)
        is_wx = str(self.request.data.get('is_wx', None))
        is_ylx = str(self.request.data.get('is_ylx', None))
        if apply_state not in ['1', '0']:
            return Response({'error': '无效审核参数'}, status=status.HTTP_400_BAD_REQUEST)
        instance = self.get_object()
        if instance.apply_state != 1:
            return Response({'error': '申请单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if apply_state == '0':
            if not return_msg:
                return Response({'error': '请提交驳回原因'}, status=status.HTTP_400_BAD_REQUEST)
            instance.return_msg = return_msg
            instance.apply_state = 3
            instance.wx_is_enter = 5
            instance.ylx_is_enter = 5
            instance.operation_user_id = user.id
            instance.operation_time = datetime.datetime.now()
            instance.save()
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
        else:
            if is_wx not in ['1', '0']:
                return Response({'error': '无效微信路径参数'}, status=status.HTTP_400_BAD_REQUEST)
            if is_ylx not in ['1', '0']:
                return Response({'error': '无效邮乐享路径参数'}, status=status.HTTP_400_BAD_REQUEST)
            if user.platform == 2:
                check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=2, wx_is_enter=1)
            else:
                check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=1, wx_is_enter=1)
            if check_history:
                is_enter = 4
            else:
                is_enter = 1
            instance.apply_state = 2
            instance.wx_is_enter = is_enter
            instance.ylx_is_enter = is_enter
            instance.is_wx = is_wx
            instance.is_ylx = is_ylx
            instance.operation_user_id = user.id
            instance.operation_time = datetime.datetime.now()
            instance.save()
            if is_enter == 1:
                update_stock_usable_merchant.delay({'id': instance.id})
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class AliDiscountCouponInfoModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = AliDiscountCouponInfoFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('mobile', 'login_id')

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        alidiscountcoupon_level_id = self.request.query_params.get('alidiscountcoupon_level_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        if alidiscountcoupon_level_id:
            try:
                couponlevel = AliDiscountCouponLevel.objects.get(id=alidiscountcoupon_level_id)
                self.request.data['acitivty_info'] = AliDiscountCouponLevelListModelSerializer(couponlevel).data
            except:
                self.request.data['acitivty_info'] = {}
        if level.level == 0:
            queryset = AliDiscountCouponInfo.objects.all()
        elif level.level == 1:
            queryset = AliDiscountCouponInfo.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = AliDiscountCouponInfo.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = AliDiscountCouponInfo.objects.filter(level__district_id=level.id)
        else:
            queryset = AliDiscountCouponInfo.objects.filter(level__branch_id=level.id)
        return queryset.order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponInfoListModelSerializer
        else:
            return AliDiscountCouponInfoRetrieveModelSerializer

    def export_discountinfo(self, request):
        user = self.request.iser
        activity_id = self.request.query_params.get('activity_id', None)
        alidiscountcoupon_level_id = self.request.query_params.get('alidiscountcoupon_level_id', None)
        level_id = self.request.query_params.get('level_id', None)
        status = self.request.query_params.get('status', None)
        search = self.request.query_params.get('search', None)
        level = user.level
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id != 0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND mobile LIKE "%{search}%"'
        if activity_id:
            condition = condition + f' AND alidiscountcoupon_id in ({activity_id})'
        if status:
            condition = condition + f' AND status in ({status})'
        if alidiscountcoupon_level_id:
            condition = condition + f' AND alidiscountcoupon_level_id={alidiscountcoupon_level_id}'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            # sql = f'''
            # SELECT r.*,s.goods_name FROM (SELECT m.*,n.coupons_id FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id FROM tb_ali_discount_coupon_info {condition})AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,order_id FROM tb_goods_coupons GROUP BY order_id)AS n ON m.order_id=n.order_id)AS r LEFT JOIN (SELECT GROUP_CONCAT(q.name)AS goods_name,q.order_id FROM (SELECT o.*,p.name FROM (SELECT order_id,goods_id FROM tb_order_goods)AS o LEFT JOIN (SELECT id,name FROM tb_goods)AS p ON o.goods_id=p.id)AS q GROUP BY q.order_id)AS s ON r.order_id=s.order_id;
            # '''
            sql = f'''
            SELECT m.*,n.vice_idcode,vice_realname FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name,coupon_way,coupon_channel FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id,customeruservice_id,out_biz_no,user_id,out_biz_order,voucher_id,login_id FROM tb_ali_discount_coupon_info {condition})AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name,coupon_way,coupon_channel FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info WHERE order_species=2)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT id,realname AS vice_realname,idcode AS vice_idcode FROM tb_u_customer_user_vice)AS n ON m.customeruservice_id=n.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT r.*,s.goods_name FROM (SELECT m.*,n.coupons_id FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id FROM tb_ali_discount_coupon_info)AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,order_id FROM tb_goods_coupons GROUP BY order_id)AS n ON m.order_id=n.order_id)AS r LEFT JOIN (SELECT GROUP_CONCAT(q.name)AS goods_name,q.order_id FROM (SELECT o.*,p.name FROM (SELECT order_id,goods_id FROM tb_order_goods)AS o LEFT JOIN (SELECT id,name FROM tb_goods)AS p ON o.goods_id=p.id)AS q GROUP BY q.order_id)AS s ON r.order_id=s.order_id;
            '''
            cursor.execute(sql)
        ziduan = ['id', '优惠券ID', '领取手机号', '领取状态', '领取人姓名', '领取人证件号码', '派发人姓名', '派发人所属网点', '网点机构号',
                  '派发时间', '撤销时间', '活动名称', '数量', '订单金额', '实际支付金额', '下单时间', '订单号', '派发单号', 'openid', '三方订单号']
        cols = ['id', 'voucher_id', 'mobile', 'status', 'realname', 'idcode', 'nickname', 'name', 'account', 'gmt_distributed', 'gmt_undo', 'activity_name',
                'total_count', 'total_price', 'realpay_amount', 'create_time', 'trade_no', 'out_biz_no', 'user_id', 'out_biz_order']
        response = StreamingHttpResponse(self.get_discountinfo_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('优惠券派发核销数据.csv'))
        return response

    def get_discountinfo_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            0: '待领取',
            1: '待核销',
            2: '不可用',
            3: '删除状态',
            4: '发送中',
            5: '已转增',
            6: '未领取',
            7: '已核销',
            8: '使用中',
            9: '已退款',
            10: '退款中',
            11: '未激活',
            12: '已过期',
            13: '已撤销',
            14: '领取失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'status':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                elif col in ['realname']:
                    if row['customeruservice_id']:
                        tmp_str += '"%s",' % (str(row['vice_realname']).encode('GBK', 'ignore').decode('gbk') if row['vice_realname'] else '')
                    else:
                        tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['idcode']:
                    if row['customeruservice_id']:
                        tmp_str += '"\'%s",' % (str(row['vice_idcode']).encode('GBK', 'ignore').decode('gbk') if row['vice_idcode'] else '')
                    else:
                        tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col == 'mobile':
                    if row['coupon_way'] == 5 and row['coupon_channel'] == 1:
                        tmp_str += '"%s",' % (str(row['login_id']).encode('GBK', 'ignore').decode('gbk') if row['login_id'] else '')
                    else:
                        tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['trade_no', 'coupons_id', 'out_biz_no', 'out_biz_order']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.status in [1, 8, 9]:
            alidiscountcoupon = instance.alidiscountcoupon
            if alidiscountcoupon.coupon_channel == 1:
                alipayopen = C_AlipayOpen()
                result = json.loads(alipayopen.voucherquery(instance.voucher_id))
                if result['status'] == 'USED':
                    alidiscountcoupon.use_count += 1
                    alidiscountcoupon.save()
                    try:
                        if 'bill_details' in result:
                            for bill_datail in result['bill_details']:
                                instance.gmt_use = bill_datail['gmt_create']
                                bill_datail['voucherinfo_id'] = instance.id
                                AliDiscountCouponBillDetails.objects.create(**bill_datail)
                    except:
                        pass
                    try:
                        alidiscountcoupon_level = instance.alidiscountcoupon_level
                        alidiscountcoupon_level.use_number += 1
                        alidiscountcoupon_level.p_use_number += 1
                        alidiscountcoupon_level.save()
                        relation_set = alidiscountcoupon_level.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_use_number += 1
                            parent.save()
                    except:
                        pass
                instance.status = instance.STATUS_ENUM[result['status']]
                instance.save()
            elif alidiscountcoupon.coupon_channel == 2:
                coupon_id = instance.voucher_id
                openid = instance.user_id
                appid = instance.appid
                if alidiscountcoupon.platform_id == 13:
                    distribute_channel = Channel.objects.get(id=13)
                else:
                    distribute_channel = Channel.objects.get(id=9)
                result = favor_query_coupons_sichun(coupon_id, openid, appid, distribute_channel)
                try:
                    if result['status'] == 'USED':
                        alidiscountcoupon.use_count += 1
                        alidiscountcoupon.save()
                        try:
                            if 'bill_details' in result:
                                for bill_datail in result['bill_details']:
                                    instance.gmt_use = bill_datail['gmt_create']
                                    bill_datail['voucherinfo_id'] = instance.id
                                    AliDiscountCouponBillDetails.objects.create(**bill_datail)
                        except:
                            pass
                        try:
                            alidiscountcoupon_level = instance.alidiscountcoupon_level
                            alidiscountcoupon_level.use_number += 1
                            alidiscountcoupon_level.p_use_number += 1
                            alidiscountcoupon_level.save()
                            relation_set = alidiscountcoupon_level.child_set.all()
                            for relation in relation_set:
                                parent = relation.parent
                                parent.p_use_number += 1
                                parent.save()
                        except:
                            pass
                        instance.status = 7
                        instance.gmt_use = datetime.datetime.now()
                    elif result['status'] == 'EXPIRED':
                        instance.status = 12
                    instance.save()
                except:
                    pass
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class AliDiscountCouponMerchantModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = AliDiscountCouponMerchantFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'merchant__wyfMerchantID', 'sub_mchid')

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = AliDiscountCouponMerchant.objects.all()
        elif level.level == 1:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__prov_id=level.id)
        elif level.level == 2:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__city_id=level.id)
        elif level.level == 3:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__district_id=level.id)
        else:
            queryset = AliDiscountCouponMerchant.objects.filter(merchant__level__branch_id=level.id)
        return queryset

    def get_serializer_class(self):
        return AliDiscountCouponMerchantModelSerializer


class CustomizeActivityModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('activity_name',)
    filter_class = CustomizeActivityFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        prize_type = self.request.query_params.get('prize_type', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = CustomizeActivity.objects.all()
        elif level.level == 1:
            queryset = CustomizeActivity.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = CustomizeActivity.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = CustomizeActivity.objects.filter(level__district_id=level.id)
        else:
            queryset = CustomizeActivity.objects.filter(level__branch_id=level.id)
        if prize_type:
            try:
                prize_type = prize_type.split(',')
                if len(prize_type) == 1:
                    queryset = queryset.filter(prize_type__contains=prize_type[0])
                elif len(prize_type) == 2:
                    queryset = queryset.filter(Q(prize_type__contains=prize_type[0]) | Q(prize_type__contains=prize_type[1]))
                elif len(prize_type) == 3:
                    queryset = queryset.filter(Q(prize_type__contains=prize_type[0]) | Q(prize_type__contains=prize_type[1]) | Q(prize_type__contains=prize_type[2]))
            except:
                pass
        return queryset.order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return CustomizeActivityListModelSerializer
        else:
            return CustomizeActivityRetrieveModelSerializer

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        level_id = self.request.data.get('level_id', None)
        activity_name = self.request.data.get('activity_name', None)
        available_begin_time = self.request.data.get('available_begin_time', None)
        available_end_time = self.request.data.get('available_end_time', None)
        activity_description = self.request.data.get('activity_description', None)
        activity_type = self.request.data.get('activity_type', None)
        prize_type = self.request.data.get('prize_type', None)
        lucky_count_by_user = self.request.data.get('lucky_count_by_user', None)
        total_count = self.request.data.get('total_count', 0)
        is_business_form = self.request.data.get('is_business_form', 0)
        max_number = self.request.data.get('max_number', None)
        drawdown_platform_id = self.request.data.get('drawdown_platform_id', '3')
        if not all([activity_type, prize_type, level_id, activity_name, available_begin_time, available_end_time, activity_description, lucky_count_by_user]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            lucky_count_by_user = int(lucky_count_by_user)
        except:
            return Response({'error': '参与次数必须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(activity_type) not in ['1', '2', '3', '4', '5', '6', '11']:
            return Response({'error': '活动类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            level = Level.objects.get(id=level_id)
        except:
            return Response({'error': '无效层级id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            available_begin_time = datetime.datetime.strptime(available_begin_time, '%Y-%m-%d %H:%M:%S')
            available_end_time = datetime.datetime.strptime(available_end_time, '%Y-%m-%d %H:%M:%S')
        except:
            return Response({'error': '活动时间参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if available_end_time < datetime.datetime.now():
            return Response({'error': '活动结束时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
        if available_begin_time > available_end_time:
            return Response({'error': '活动开始时间需小于结束时间'}, status=status.HTTP_400_BAD_REQUEST)
        if is_business_form:
            if str(is_business_form) not in ['0', '1']:
                return Response({'error': '是否填写业务表单参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(activity_type) == '1':
            total_count = 9
            if lucky_count_by_user > total_count:
                return Response({'error': '随机抽奖类型活动最大参与数为9'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(activity_type) == '2':
            total_count = 6
        elif str(activity_type) == '4':
            total_count = 8
        try:
            prize_type1 = prize_type.split(',')
            for i in prize_type1:
                if i not in '1,2,3,4,5,6,7,8':
                    return Response({'error': '奖品类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            return Response({'error': '奖品类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(activity_type) == '11':
            if not max_number:
                return Response({'error': '员工派券包活动请上传活动最大数量'}, status=status.HTTP_400_BAD_REQUEST)
            if str(drawdown_platform_id) not in ['3', '4']:
                return Response({'error': '派发平台有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                customize_activity_data = {}
                customize_activity_data['activity_name'] = activity_name
                customize_activity_data['activity_description'] = activity_description
                customize_activity_data['activity_type'] = activity_type
                customize_activity_data['prize_type'] = prize_type
                customize_activity_data['level_id'] = level_id
                customize_activity_data['available_begin_time'] = available_begin_time
                customize_activity_data['available_end_time'] = available_end_time
                customize_activity_data['create_user_id'] = user.id
                customize_activity_data['lucky_count_by_user'] = lucky_count_by_user
                customize_activity_data['total_count'] = total_count
                customize_activity_data['is_business_form'] = is_business_form
                if str(activity_type) == '11':
                    customize_activity_data['max_number'] = max_number
                    customize_activity_data['remain_number'] = max_number
                    customize_activity_data['take_number'] = 0
                identify = random_str(48)
                common_url = f'https://api.sutpay.com/customer/customize/?identify={identify}&activity_type={activity_type}'
                common_qrcode = f'youhuiquanyi/customizeactivitylevel/{identify}.png'
                common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                customize_activity_data['identify'] = identify
                customize_activity_data['common_qrcode'] = common_qrcode
                customize_activity_data['common_url'] = common_url
                customize_activity_data['drawdown_platform_id'] = drawdown_platform_id
                customize_activity = CustomizeActivity.objects.create(**customize_activity_data)
                activity_id = f'CTA{str(customize_activity.id).zfill(8)}'
                customize_activity.activity_id = activity_id
                customize_activity.save()
                transaction.savepoint_commit(save_id)
                return Response({'success': '创建成功', 'id': customize_activity.id}, status=status.HTTP_200_OK)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '创建失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        is_need_auth = self.request.data.get('is_need_auth', None)
        is_white = self.request.data.get('is_white', None)
        available_begin_time = self.request.data.get('available_begin_time', None)
        available_end_time = self.request.data.get('available_end_time', None)
        activity_description = self.request.data.get('activity_description', None)
        activity_status = self.request.data.get('activity_status', None)
        if available_begin_time and available_end_time:
            try:
                available_begin_time = datetime.datetime.strptime(available_begin_time, '%Y-%m-%d %H:%M:%S')
                available_end_time = datetime.datetime.strptime(available_end_time, '%Y-%m-%d %H:%M:%S')
            except:
                return Response({'error': '活动时间参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            if available_end_time < datetime.datetime.now():
                return Response({'error': '活动结束时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
            if available_begin_time > available_end_time:
                return Response({'error': '活动开始时间需小于结束时间'}, status=status.HTTP_400_BAD_REQUEST)
            instance.available_begin_time = available_begin_time
            instance.available_end_time = available_end_time
        if activity_description:
            instance.activity_description = activity_description
        if activity_status:
            if str(activity_status) == '1':
                if instance.activity_status == 2:
                    return Response({'error': '已结束活动不得开启'}, status=status.HTTP_400_BAD_REQUEST)
                instance.activity_status = 1
            elif str(activity_status) == '2':
                if instance.activity_status != 1:
                    return Response({'error': '只有进行中的活动可以暂停'}, status=status.HTTP_400_BAD_REQUEST)
                instance.activity_status = 4
        if str(is_need_auth) == '0':
            instance.is_need_auth = 0
        elif str(is_need_auth) == '1':
            instance.is_need_auth = 1
        if str(is_white) == '0':
            instance.is_white = 0
        elif str(is_white) == '1':
            instance.is_white = 1
        try:
            instance.save()
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '操作失败'}, status=status.HTTP_400_BAD_REQUEST)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.activity_status == 2:
            return Response({'error': '已结束活动不得绑定活动'}, status=status.HTTP_400_BAD_REQUEST)
        activity_array = self.request.data.get('activity_array', None)
        if not activity_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                if instance.activity_type == 1:
                    customizeactivityrules_set = instance.customizeactivityrules_set.all().aggregate(Sum('count'))
                    if customizeactivityrules_set['count__sum']:
                        total_count = instance.total_count - customizeactivityrules_set['count__sum']
                    else:
                        total_count = instance.total_count
                    for activity in activity_array:
                        if 'prize_type' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少奖品类型'}, status=status.HTTP_400_BAD_REQUEST)
                        if 'activity_id' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少活动id'}, status=status.HTTP_400_BAD_REQUEST)
                        if 'count' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少活动中奖次数'}, status=status.HTTP_400_BAD_REQUEST)
                        try:
                            count = int(activity['count'])
                        except:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数有误,活动中奖次数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                        total_count -= count
                        if total_count < 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数有误,活动中奖次数须不能大于活动总奖项'}, status=status.HTTP_400_BAD_REQUEST)
                        if str(activity['prize_type']) in ['1', '2']:
                            alidiscountcoupon = AliDiscountCoupon.objects.filter(id=activity['activity_id']).first()
                            if not alidiscountcoupon:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
                            if alidiscountcoupon.coupon_way != 6:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '活动类型不支持'}, status=status.HTTP_400_BAD_REQUEST)
                            alidiscountcouponchannelcommonvoucher = alidiscountcoupon.alidiscountcouponchannelcommonvoucher
                            if alidiscountcouponchannelcommonvoucher.join_limit_by_user == 1:
                                if count > instance.lucky_count_by_user:
                                    if instance.lucky_count_by_user > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                                else:
                                    if count > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = count
                            customize_activity_rules_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.get_or_create(defaults=customize_activity_rules_data, customizeactivity_id=instance.id, alidiscountcoupon_id=alidiscountcoupon.id)
                        elif str(activity['prize_type']) == '3':
                            cashactivity = CashActivity.objects.filter(id=activity['activity_id']).first()
                            if not cashactivity:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
                            if cashactivity.activity_type != 7:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '活动类型不支持'}, status=status.HTTP_400_BAD_REQUEST)
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = activity['count']
                            customize_activity_rules_data['cashactivity_id'] = cashactivity.id
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.get_or_create(defaults=customize_activity_rules_data, customizeactivity_id=instance.id, cashactivity_id=cashactivity.id)
                        else:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '奖品类型有误'}, status=status.HTTP_400_BAD_REQUEST)
                elif instance.activity_type in [2, 4]:
                    customizeactivityrules_set = instance.customizeactivityrules_set.all()
                    if customizeactivityrules_set:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '不可重复配置'}, status=status.HTTP_400_BAD_REQUEST)
                    if len(activity_array) != instance.total_count:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '参数格式有误,请上传对应扇叶数奖品'}, status=status.HTTP_400_BAD_REQUEST)
                    total_count = 100
                    for activity in activity_array:
                        if 'prize_type' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少奖品类型'}, status=status.HTTP_400_BAD_REQUEST)
                        if str(activity['prize_type']) in ['1', '2', '3']:
                            if 'activity_id' not in activity:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '参数格式有误,缺少活动id'}, status=status.HTTP_400_BAD_REQUEST)
                        if 'count' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少活动中奖次数'}, status=status.HTTP_400_BAD_REQUEST)
                        try:
                            count = int(activity['count'])
                        except:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数有误,活动中奖次数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                        total_count -= count
                        if total_count < 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '随机概率值不得大于100'}, status=status.HTTP_400_BAD_REQUEST)
                        if str(activity['prize_type']) in ['1', '2']:
                            alidiscountcoupon = AliDiscountCoupon.objects.filter(id=activity['activity_id']).first()
                            if not alidiscountcoupon:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
                            if alidiscountcoupon.coupon_way != 6:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '活动类型不支持'}, status=status.HTTP_400_BAD_REQUEST)
                            alidiscountcouponchannelcommonvoucher = alidiscountcoupon.alidiscountcouponchannelcommonvoucher
                            if alidiscountcouponchannelcommonvoucher.join_limit_by_user == 1:
                                if count > instance.lucky_count_by_user:
                                    if instance.lucky_count_by_user > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                                else:
                                    if count > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = count
                            customize_activity_rules_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.create(**customize_activity_rules_data)
                        elif str(activity['prize_type']) == '3':
                            cashactivity = CashActivity.objects.filter(id=activity['activity_id']).first()
                            if not cashactivity:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
                            if cashactivity.activity_type != 7:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '活动类型不支持'}, status=status.HTTP_400_BAD_REQUEST)
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = activity['count']
                            customize_activity_rules_data['cashactivity_id'] = cashactivity.id
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.create(**customize_activity_rules_data)
                        elif str(activity['prize_type']) == '4':
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = activity['count']
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.create(**customize_activity_rules_data)
                        else:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '奖品类型有误'}, status=status.HTTP_400_BAD_REQUEST)
                elif instance.activity_type == 11:
                    for activity in activity_array:
                        if 'prize_type' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少奖品类型'}, status=status.HTTP_400_BAD_REQUEST)
                        if 'activity_id' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少活动id'}, status=status.HTTP_400_BAD_REQUEST)
                        if 'count' not in activity:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数格式有误,缺少活动中奖次数'}, status=status.HTTP_400_BAD_REQUEST)
                        try:
                            count = int(activity['count'])
                        except:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '参数有误,活动中奖次数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                        if str(activity['prize_type']) in ['2', '8']:
                            alidiscountcoupon = AliDiscountCoupon.objects.filter(id=activity['activity_id']).first()
                            if not alidiscountcoupon:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '无效活动参数'}, status=status.HTTP_400_BAD_REQUEST)
                            if alidiscountcoupon.coupon_way != 6:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '活动类型不支持'}, status=status.HTTP_400_BAD_REQUEST)
                            if alidiscountcoupon.remain_number < count* instance.max_number:
                                transaction.savepoint_rollback(save_id)
                                return Response({'error': '券活动剩余数量不足券活动数'}, status=status.HTTP_400_BAD_REQUEST)
                            alidiscountcouponchannelcommonvoucher = alidiscountcoupon.alidiscountcouponchannelcommonvoucher
                            if alidiscountcouponchannelcommonvoucher.join_limit_by_user == 1:
                                if count > instance.lucky_count_by_user:
                                    if instance.lucky_count_by_user > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                                else:
                                    if count > alidiscountcouponchannelcommonvoucher.join_limit_by_user_count:
                                        transaction.savepoint_rollback(save_id)
                                        return Response({'error': '活动奖品个数大于奖品参与限制'}, status=status.HTTP_400_BAD_REQUEST)
                            customize_activity_rules_data = {}
                            customize_activity_rules_data['prize_type'] = activity['prize_type']
                            customize_activity_rules_data['count'] = count
                            customize_activity_rules_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                            customize_activity_rules_data['customizeactivity_id'] = instance.id
                            CustomizeActivityRules.objects.get_or_create(defaults=customize_activity_rules_data, customizeactivity_id=instance.id, alidiscountcoupon_id=alidiscountcoupon.id)
                        else:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '奖品类型有误'}, status=status.HTTP_400_BAD_REQUEST)
                else:
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '活动类型有误,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '操作失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def allocation_customize(self, request):
        user = self.request.iser
        data_array = self.request.data.get('data_array', None)
        customizeactivity_id = self.request.data.get('customizeactivity_id', None)
        try:
            instance = self.get_queryset().get(id=customizeactivity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if not data_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.activity_status == 2:
            return Response({'error': '已结束活动不可操作'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(data_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        level_list = get_level_list(instance.level)
        if instance.activity_type != 11:
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    for level_id in data_array:
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        customizeactivitylevel_data = {}
                        customizeactivitylevel_data['level_id'] = level_id
                        customizeactivitylevel_data['customizeactivity_id'] = instance.id
                        identify = random_str()
                        common_url = f'https://api.sutpay.com/customer/customize/?identify={identify}&activity_type={instance.activity_type}'
                        common_qrcode = f'youhuiquanyi/customizeactivitylevel/{identify}.png'
                        common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                        customizeactivitylevel_data['identify'] = identify
                        customizeactivitylevel_data['common_url'] = common_url
                        customizeactivitylevel_data['common_qrcode'] = common_qrcode
                        customizeactivitylevel, create = CustomizeActivityLevel.objects.get_or_create(defaults=customizeactivitylevel_data, customizeactivity_id=instance.id, level_id=level_id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        else:
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    total_number = 0
                    for data in data_array:
                        level_id = data['level_id']
                        max_number = int(data['max_number'])
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        total_number += max_number
                    while True:
                        customizeactivity = CustomizeActivity.objects.get(id=customizeactivity_id)
                        origin_take_number = customizeactivity.take_number
                        origin_remain_number = customizeactivity.remain_number
                        if origin_remain_number < total_number:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '额度不足分配'}, status=status.HTTP_400_BAD_REQUEST)
                        new_take_number = origin_take_number + total_number
                        new_remain_number = origin_remain_number - total_number
                        result = CustomizeActivity.objects.filter(id=customizeactivity_id, take_number=origin_take_number, remain_number=origin_remain_number).update(take_number=new_take_number,remain_number=new_remain_number)
                        if result == 0:
                            continue
                        break
                    for data in data_array:
                        level_id = data['level_id']
                        max_number = int(data['max_number'])
                        customizeactivitylevel_data = {}
                        customizeactivitylevel_data['level_id'] = level_id
                        customizeactivitylevel_data['customizeactivity_id'] = instance.id
                        identify = random_str()
                        common_url = f'https://api.sutpay.com/customer/customize/?identify={identify}&activity_type={instance.activity_type}'
                        common_qrcode = f'youhuiquanyi/customizeactivitylevel/{identify}.png'
                        common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                        customizeactivitylevel_data['identify'] = identify
                        customizeactivitylevel_data['common_url'] = common_url
                        customizeactivitylevel_data['common_qrcode'] = common_qrcode
                        customizeactivitylevel_data['max_number'] = max_number
                        customizeactivitylevel_data['remain_number'] = max_number
                        customizeactivitylevel_data['take_number'] = 0
                        customizeactivitylevel_data['receive_number'] = 0
                        customizeactivitylevel, create = CustomizeActivityLevel.objects.get_or_create(defaults=customizeactivitylevel_data, customizeactivity_id=instance.id, level_id=level_id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)

    def allocation_customize_level(self, request):
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        search = self.request.query_params.get('search', None)
        if not customizeactivity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=customizeactivity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level = instance.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(customizeactivitylevel__customizeactivity_id=instance.id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def update_customize_white_table(self, request):
        customizeactivity_id = self.request.data.get('customizeactivity_id', None)
        mobile_array = self.request.data.get('mobile_array', None)
        try:
            instance = self.get_queryset().get(id=customizeactivity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            # 暴力回滚
            try:
                customizeactivitywhitetable_set = instance.customizeactivitywhitetable_set.all().delete()
                for mobile in mobile_array:
                    if not re.match(r'^1[3-9]\d{9}$', mobile):
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': f'{mobile}非手机号格式'}, status=status.HTTP_400_BAD_REQUEST)
                    CustomizeActivityWhiteTable.objects.create(customizeactivity_id=customizeactivity_id, mobile=mobile)
                transaction.savepoint_commit(save_id)
                return Response({'success': '修改成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def customize_white_table(self, request):
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        try:
            instance = self.get_queryset().get(id=customizeactivity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        customizeactivitywhitetable_set = instance.customizeactivitywhitetable_set.all().values_list('mobile', flat=True)
        return Response({'data': list(customizeactivitywhitetable_set)}, status=status.HTTP_200_OK)


class CustomizeActivityRulesModelViewSet(ModelViewSet):

    pagination_class = MyPage
    serializer_class = CustomizeActivityRulesListModelSerializer

    def get_queryset(self):
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        queryset = CustomizeActivityRules.objects.filter(customizeactivity_id=customizeactivity_id)
        return queryset


class CustomizeActivityLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    search_fields = ('level__name', )
    filter_class = CustomizeActivityLevelFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = CustomizeActivityLevel.objects.all()
        elif level.level == 1:
            queryset = CustomizeActivityLevel.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = CustomizeActivityLevel.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = CustomizeActivityLevel.objects.filter(level__district_id=level.id)
        else:
            queryset = CustomizeActivityLevel.objects.filter(level__branch_id=level.id)
        return queryset.order_by('-id')

    def get_serializer_class(self):
        return CustomizeActivityLevelListModelSerializer
